diff --git a/.asf.yaml b/.asf.yaml index d6024c10a0..8bcc57a651 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -38,7 +38,7 @@ github: - hacktoberfest enabled_merge_buttons: squash: true - merge: true + merge: false rebase: false protected_branches: master: @@ -47,6 +47,25 @@ github: required_pull_request_reviews: dismiss_stale_reviews: true required_approving_review_count: 2 + # Attempt to make the auto-generated github emails more easily readable in email clients. + custom_subjects: + new_pr: "[PR] {title} ({repository})" + close_pr: "Re: [PR] {title} ({repository})" + comment_pr: "Re: [PR] {title} ({repository})" + diffcomment: "Re: [PR] {title} ({repository})" + merge_pr: "Re: [PR] {title} ({repository})" + new_issue: "[I] {title} ({repository})" + comment_issue: "Re: [I] {title} ({repository})" + close_issue: "Re: [I] {title} ({repository})" + catchall: "[GH] {title} ({repository})" + new_discussion: "[D] {title} ({repository})" + edit_discussion: "Re: [D] {title} ({repository})" + close_discussion: "Re: [D] {title} ({repository})" + close_discussion_with_comment: "Re: [D] {title} ({repository})" + reopen_discussion: "Re: [D] {title} ({repository})" + new_comment_discussion: "Re: [D] {title} ({repository})" + edit_comment_discussion: "Re: [D] {title} ({repository})" + delete_comment_discussion: "Re: [D] {title} ({repository})" notifications: commits: commits@eventmesh.apache.org # Send all issue emails (new, closed, comments) to issues@ diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..b27bb300d7 --- /dev/null +++ b/.gitattributes @@ -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. +# +*.sh text eol=lf +gradlew text eol=lf +*.{cmd,[cC][mM][dD]} text eol=crlf +*.{bat,[bB][aA][tT]} text eol=crlf \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 7eefbc7944..a19b99ed3d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -55,6 +55,11 @@ body: description: Describe the EventMesh version. options: - master + - 1.10.0 + - 1.9.0 + - 1.8.0 + - 1.7.0 + - 1.6.0 - 1.5.0 - 1.4.0 - 1.3.0 @@ -89,6 +94,7 @@ body: description: Anything else we need to know? placeholder: > Add your debug logs here. + render: Java validations: required: false @@ -101,6 +107,14 @@ body: options: - label: Yes I am willing to submit a PR! + - type: checkboxes + attributes: + label: Code of Conduct + description: > + The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.. + options: + - label: I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct) * + - 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 index 9841b8caf8..1fa6ef875a 100644 --- a/.github/ISSUE_TEMPLATE/documentation_related.yml +++ b/.github/ISSUE_TEMPLATE/documentation_related.yml @@ -55,6 +55,14 @@ body: options: - label: Yes I am willing to submit a PR! + - type: checkboxes + attributes: + label: Code of Conduct + description: > + The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.. + options: + - label: I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct) * + - type: markdown attributes: - value: "Thanks for completing our form!" \ No newline at end of file + value: "Thanks for completing our form!" diff --git a/.github/ISSUE_TEMPLATE/enhancement_request.yml b/.github/ISSUE_TEMPLATE/enhancement_request.yml index 0abb545083..cd9e0c59ae 100644 --- a/.github/ISSUE_TEMPLATE/enhancement_request.yml +++ b/.github/ISSUE_TEMPLATE/enhancement_request.yml @@ -65,6 +65,13 @@ body: options: - label: Yes I am willing to submit a PR! + - type: checkboxes + attributes: + label: Code of Conduct + description: > + The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.. + options: + - label: I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct) * - type: markdown attributes: - value: "Thanks for completing our form!" \ No newline at end of file + value: "Thanks for completing our form!" diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 9969b3d10d..fe9d032068 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -57,6 +57,14 @@ body: options: - label: Yes I am willing to submit a PR! + - type: checkboxes + attributes: + label: Code of Conduct + description: > + The Code of Conduct helps create a safe space for everyone. We require that everyone agrees to it.. + options: + - label: I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct) * + - 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 index 723e1356d7..82ce502400 100644 --- a/.github/ISSUE_TEMPLATE/unit_test.yml +++ b/.github/ISSUE_TEMPLATE/unit_test.yml @@ -41,7 +41,7 @@ body: attributes: label: Read the unit testing guidelines description: > - Read the [unit testing guidelines](https://github.com/apache/eventmesh/blob/master/docs/en/contribute/02-write-unit-test.md) before writing unit test code. + Read the [unit testing guidelines](https://eventmesh.apache.org/community/contribute/write-unit-test) before writing unit test code. options: - label: > I have read. @@ -83,4 +83,4 @@ body: - type: markdown attributes: - value: "Thanks for completing our form!" \ No newline at end of file + value: "Thanks for completing our form!" diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 6595e7f6ee..428cda5f55 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -23,21 +23,17 @@ (If this PR fixes a GitHub issue, please add `Fixes #` or `Closes #`.) --> -Fixes #. +Fixes #issue_id ### 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) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml deleted file mode 100644 index 67af54f16c..0000000000 --- a/.github/workflows/build.yaml +++ /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. -# -name: Build -on: - push: - branches: - - master - -jobs: - docker: - runs-on: ubuntu-latest - steps: - - name: Login to DockerHub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - name: Build and push - uses: docker/build-push-action@v3 - with: - push: true - tags: eventmesh/eventmesh:latest - file: ./docker/Dockerfile - context: ./ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fce610af8..e6018573c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,20 +33,33 @@ jobs: matrix: os: [ ubuntu-latest, macOS-latest ] java: [ 8, 11 ] + language: ['java'] runs-on: ${{ matrix.os }} steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + - if: matrix.language == 'cpp' || matrix.language == 'csharp' + name: Build C + run: | + git submodule init + git submodule update + make -C ./eventmesh-sdks/eventmesh-sdk-c + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + + - name: Set up JDK 11 + uses: actions/setup-java@v3 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 }} + distribution: 'zulu' + java-version: 11 + + - name: GenerateGrammarSource + run: ./gradlew clean generateGrammarSource --parallel --daemon + env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }} - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@v3 @@ -54,24 +67,16 @@ jobs: distribution: 'zulu' java-version: ${{ matrix.java }} - - name: Cache Gradle packages - uses: actions/cache@v3 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: ${{ runner.os }}-gradle- - # https://docs.gradle.org/current/userguide/performance.html - name: Build - run: ./gradlew clean build jar dist jacocoTestReport --parallel --daemon + run: ./gradlew clean build dist jacocoTestReport -x spotlessJava -x generateGrammarSource --parallel --daemon + env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }} - name: Install plugin run: ./gradlew installPlugin - - - name: Perform CodeQL analysis - uses: github/codeql-action/analyze@v2 + env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }} - name: Upload coverage report to codecov.io run: bash <(curl -s https://codecov.io/bash) || echo 'Failed to upload coverage report!' @@ -91,4 +96,6 @@ jobs: - 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" + ./gradlew clean dist -x spotlessJava -x test -x checkstyleMain -x javaDoc && ./gradlew installPlugin && ./gradlew tar && sh tools/dependency-check/check-dependencies.sh && echo "Thirty party dependencies check success" + env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..d8a345a39f --- /dev/null +++ b/.github/workflows/codeql.yml @@ -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. +# + +name: "CodeQL" + +on: + push: + branches: [ '*' ] + pull_request: + branches: [ '*' ] + +jobs: + build: + name: Analyze + strategy: + fail-fast: false + matrix: + language: ['java', 'go'] + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + 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: Setup Gradle + uses: gradle/gradle-build-action@v2 + if: matrix.language == 'java' + + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: 11 + if: matrix.language == 'java' + + # https://docs.gradle.org/current/userguide/performance.html + - name: Build + run: ./gradlew clean assemble compileTestJava --no-build-cache --parallel --daemon + env: + GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GE_ACCESS_TOKEN }} + if: matrix.language == 'java' + + - name: Perform CodeQL analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml new file mode 100644 index 0000000000..ab49c8204e --- /dev/null +++ b/.github/workflows/docker.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. +# +name: Docker +on: + release: + types: [released] + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USER }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Docker meta + id: meta + uses: docker/metadata-action@v4 + with: + images: | + apache/eventmesh + + - name: Build and push + uses: docker/build-push-action@v4 + with: + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + file: ./docker/Dockerfile_jdk8 + context: ./ diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml index 9ddc0315c6..740ea6a246 100644 --- a/.github/workflows/greetings.yml +++ b/.github/workflows/greetings.yml @@ -26,7 +26,7 @@ jobs: name: Greeting runs-on: ubuntu-latest steps: - - uses: actions/first-interaction@v1 + - uses: actions/first-interaction@v1.3.0 with: repo-token: ${{ secrets.GITHUB_TOKEN }} issue-message: | @@ -43,7 +43,7 @@ jobs: |WeChat Assistant|WeChat Public Account|Slack| |-|-|-| - |||[Join Slack Chat](https://join.slack.com/t/apacheeventmesh/shared_invite/zt-1t1816dli-I0t3OE~IpdYWrZbIWhMbXg)| + |||[Join Slack Chat](https://join.slack.com/t/the-asf/shared_invite/zt-1y375qcox-UW1898e4kZE_pqrNsrBM2g)| Mailing Lists: | Name | Description |Subscribe |Unsubscribe|Archive @@ -65,7 +65,7 @@ jobs: |WeChat Assistant|WeChat Public Account|Slack| |-|-|-| - |||[Join Slack Chat](https://join.slack.com/t/apacheeventmesh/shared_invite/zt-1t1816dli-I0t3OE~IpdYWrZbIWhMbXg)| + |||[Join Slack Chat](https://join.slack.com/t/the-asf/shared_invite/zt-1y375qcox-UW1898e4kZE_pqrNsrBM2g)| Mailing Lists: | Name | Description |Subscribe |Unsubscribe|Archive diff --git a/.gitignore b/.gitignore index ef70f919e3..a22c82f795 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ logs *.log *.log.* .idea +!/.idea/icon.png build .classpath .project @@ -22,7 +23,6 @@ classes package-lock.json node_modules .run -*.log h2/db.mv.db @@ -47,4 +47,7 @@ bld/ [Oo]bj/ [Ll]og/ [Ll]ogs/ -!eventmesh-runtime/bin/*.sh \ No newline at end of file +**/org/apache/eventmesh/connector/jdbc/antlr4/autogeneration/* + +#rust +Cargo.lock \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..51d401af7f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,7 @@ +[submodule "eventmesh-sdks/eventmesh-sdk-c/third_party/json-c"] + path = eventmesh-sdks/eventmesh-sdk-c/third_party/json-c + url = git@github.com:json-c/json-c.git + branch = json-c-0.17 +[submodule "eventmesh-sdks/eventmesh-sdk-c/third_party/curl"] + path = eventmesh-sdks/eventmesh-sdk-c/third_party/curl + url = git@github.com:curl/curl.git diff --git a/.idea/icon.png b/.idea/icon.png new file mode 100644 index 0000000000..59aa06dac9 Binary files /dev/null and b/.idea/icon.png differ diff --git a/.licenserc.yaml b/.licenserc.yaml index 040673a618..61d0621403 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -23,6 +23,8 @@ header: copyright-owner: Apache Software Foundation paths-ignore: + - 'eventmesh-operator/config/crd/bases' + - 'eventmesh-operator/config/rbac' - '.github/PULL_REQUEST_TEMPLATE' - '.gitmodules' - '**/.gitkeep' diff --git a/README.md b/README.md index 389d8801f7..6e6f695f64 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![License](https://img.shields.io/github/license/apache/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/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-1vpgrvm5u-hh~5H9Aj4TGThaP9tusFfw) +[![Slack Status](https://img.shields.io/badge/slack-join_chat-blue.svg?logo=slack&style=for-the-badge)](https://join.slack.com/t/the-asf/shared_invite/zt-1y375qcox-UW1898e4kZE_pqrNsrBM2g) [📦 Documentation](https://eventmesh.apache.org/docs/introduction) | @@ -30,6 +30,7 @@ ![EventMesh Architecture](resources/eventmesh-architecture-4.png) ### EventMesh Dashboard + ![EventMesh Dashboard](resources/dashboard.png) ## Features @@ -37,9 +38,9 @@ Apache EventMesh has a vast amount of features to help users achieve their goals. Let us share with you some of the key features EventMesh has to offer: - Built around the [CloudEvents](https://cloudevents.io) specification. -- Rapidty extendsible interconnector layer [connectors](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors) such as the source or sink of Saas, CloudService, and Database etc. -- Rapidty extendsible storage layer such as [Apache RocketMQ](https://rocketmq.apache.org), [Apache Kafka](https://kafka.apache.org), [Apache Pulsar](https://pulsar.apache.org), [RabbitMQ](https://rabbitmq.com), [Redis](https://redis.io), [Pravega](https://cncf.pravega.io), and [RDMS](https://en.wikipedia.org/wiki/Relational_database)(in progress) using [JDBC](https://en.wikipedia.org/wiki/Java_Database_Connectivity). -- Rapidty extendsible controller such as [Consul](https://consulproject.org/en/), [Nacos](https://nacos.io), [ETCD](https://etcd.io) and [Zookeeper](https://zookeeper.apache.org/). +- Rapidty extendsible interconnector layer [connectors](https://github.com/apache/eventmesh/tree/master/eventmesh-connectors) using [openConnect](https://github.com/apache/eventmesh/tree/master/eventmesh-openconnect) such as the source or sink of Saas, CloudService, and Database etc. +- Rapidty extendsible storage layer such as [Apache RocketMQ](https://rocketmq.apache.org), [Apache Kafka](https://kafka.apache.org), [Apache Pulsar](https://pulsar.apache.org), [RabbitMQ](https://rabbitmq.com), [Redis](https://redis.io). +- Rapidty extendsible meta such as [Consul](https://consulproject.org/en/), [Nacos](https://nacos.io), [ETCD](https://etcd.io) and [Zookeeper](https://zookeeper.apache.org/). - Guaranteed at-least-once delivery. - Deliver events between multiple EventMesh deployments. - Event schema management by catalog service. @@ -49,9 +50,11 @@ Apache EventMesh has a vast amount of features to help users achieve their goals - Easy Function develop and framework integration. ## Roadmap + Please go to the [roadmap](https://eventmesh.apache.org/docs/roadmap) to get the release history and new features of Apache EventMesh. ## Subprojects + - [EventMesh-site](https://github.com/apache/eventmesh-site): Apache official website resources for EventMesh. - [EventMesh-workflow](https://github.com/apache/eventmesh-workflow): Serverless workflow runtime for event Orchestration on EventMesh. - [EventMesh-dashboard](https://github.com/apache/eventmesh-dashboard): Operation and maintenance console of EventMesh. @@ -59,21 +62,121 @@ Please go to the [roadmap](https://eventmesh.apache.org/docs/roadmap) to get the - [EventMesh-go](https://github.com/apache/eventmesh-go): A go implementation for EventMesh runtime. ## Quick start -Here are the guidelines: -[Step 1: Deploy eventmesh-store](https://eventmesh.apache.org/docs/instruction/store) +This section of the guide will show you the steps to deploy EventMesh from [Local](#run-eventmesh-runtime-locally), [Docker](#run-eventmesh-runtime-in-docker), [K8s](#run-eventmesh-runtime-in-kubernetes). + +This section guides the launch of EventMesh according to the default configuration, if you need more detailed EventMesh deployment steps, please visit the [EventMesh official document](https://eventmesh.apache.org/docs/introduction). + +### Deployment Event Store + +> EventMesh supports [multiple Event Stores](https://eventmesh.apache.org/docs/roadmap#event-store-implementation-status), the default storage mode is `standalone`, and does not rely on other event stores as layers. + +### Run EventMesh Runtime locally + +#### 1. Download EventMesh + +Download the latest version of the Binary Distribution from the [EventMesh Download](https://eventmesh.apache.org/download/) page and extract it: + +```shell +wget https://dlcdn.apache.org/eventmesh/1.10.0/apache-eventmesh-1.10.0-bin.tar.gz +tar -xvzf apache-eventmesh-1.10.0-bin.tar.gz +cd apache-eventmesh-1.10.0 +``` + +#### 2. Run EventMesh + +Execute the `start.sh` script to start the EventMesh Runtime server. + +```shell +bash bin/start.sh +``` + +View the output log: + +```shell +tail -n 50 -f logs/eventmesh.out +``` + +When the log output shows server `state:RUNNING`, it means EventMesh Runtime has started successfully. + +You can stop the run with the following command: + +```shell +bash bin/stop.sh +``` + +When the script prints `shutdown server ok!`, it means EventMesh Runtime has stopped. + +### Run EventMesh Runtime in Docker + +#### 1. Pull EventMesh Image + +Use the following command line to download the latest version of [EventMesh](https://hub.docker.com/r/apache/eventmesh): + +```shell +sudo docker pull apache/eventmesh:latest +``` + +#### 2. Run and Manage EventMesh Container + +Use the following command to start the EventMesh container: + +```shell +sudo docker run -d --name eventmesh -p 10000:10000 -p 10105:10105 -p 10205:10205 -p 10106:10106 -t apache/eventmesh:latest +``` + + +Enter the container: + +```shell +sudo docker exec -it eventmesh /bin/bash +``` + +view the log: + +```shell +cd logs +tail -n 50 -f eventmesh.out +``` + +### Run EventMesh Runtime in Kubernetes + +#### 1. Deploy operator + +Run the following commands(To delete a deployment, simply replace `deploy` with `undeploy`): + +```shell +$ cd eventmesh-operator && make deploy +``` + +Run `kubectl get pods` 、`kubectl get crd | grep eventmesh-operator.eventmesh`to see the status of the deployed eventmesh-operator. + +```shell +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +eventmesh-operator-59c59f4f7b-nmmlm 1/1 Running 0 20s -[Step 2: Start eventmesh-runtime](https://eventmesh.apache.org/docs/instruction/runtime) +$ kubectl get crd | grep eventmesh-operator.eventmesh +connectors.eventmesh-operator.eventmesh 2024-01-10T02:40:27Z +runtimes.eventmesh-operator.eventmesh 2024-01-10T02:40:27Z +``` -[Step 3: Run our demos](https://eventmesh.apache.org/docs/instruction/demo) +#### 2. Deploy EventMesh Runtime -Besides, we also provide the docker-version guidelines for you if you prefer Docker: +Execute the following command to deploy runtime, connector-rocketmq (To delete, simply replace `create` with `delete`): -[Step 1: Deploy eventmesh-store using docker](https://eventmesh.apache.org/docs/instruction/store-with-docker) +```shell +$ make create +``` -[Step 2: Start eventmesh-runtime using docker](https://eventmesh.apache.org/docs/instruction/runtime-with-docker) +Run `kubectl get pods` to see if the deployment was successful. -[Step 3: Run our demos](https://eventmesh.apache.org/docs/instruction/demo) +```shell +NAME READY STATUS RESTARTS AGE +connector-rocketmq-0 1/1 Running 0 9s +eventmesh-operator-59c59f4f7b-nmmlm 1/1 Running 0 3m12s +eventmesh-runtime-0-a-0 1/1 Running 0 15s +``` ## Contributing @@ -106,9 +209,9 @@ Apache EventMesh is licensed under the [Apache License, Version 2.0](http://www. ## Community -|WeChat Assistant|WeChat Public Account|Slack| -|-|-|-| -|||[Join Slack Chat](https://join.slack.com/t/apacheeventmesh/shared_invite/zt-1vpgrvm5u-hh~5H9Aj4TGThaP9tusFfw)| +| WeChat Assistant | WeChat Public Account | Slack | +|---------------------------------------------------------|--------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| | | [Join Slack Chat](https://join.slack.com/t/the-asf/shared_invite/zt-1y375qcox-UW1898e4kZE_pqrNsrBM2g)(Please open an issue if this link is expired) | Bi-weekly meeting : [#Tencent meeting](https://meeting.tencent.com/dm/wes6Erb9ioVV) : 346-6926-0133 @@ -116,9 +219,9 @@ Bi-weekly meeting record : [bilibili](https://space.bilibili.com/1057662180) ### Mailing List -|Name|Description|Subscribe|Unsubscribe|Archive -|-|-|-|-|-| -|Users|User discussion|[Subscribe](mailto:users-subscribe@eventmesh.apache.org)|[Unsubscribe](mailto:users-unsubscribe@eventmesh.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.apache.org)|[Unsubscribe](mailto:dev-unsubscribe@eventmesh.apache.org)|[Mail Archives](https://lists.apache.org/list.html?dev@eventmesh.apache.org)| -|Commits|Commits to related repositories| [Subscribe](mailto:commits-subscribe@eventmesh.apache.org) |[Unsubscribe](mailto:commits-unsubscribe@eventmesh.apache.org) |[Mail Archives](https://lists.apache.org/list.html?commits@eventmesh.apache.org)| -|Issues|Issues or PRs comments and reviews| [Subscribe](mailto:issues-subscribe@eventmesh.apache.org) |[Unsubscribe](mailto:issues-unsubscribe@eventmesh.apache.org) |[Mail Archives](https://lists.apache.org/list.html?issues@eventmesh.apache.org)| +| Name | Description | Subscribe | Unsubscribe | Archive | +|-------------|---------------------------------------------------------|------------------------------------------------------------|----------------------------------------------------------------|----------------------------------------------------------------------------------| +| Users | User discussion | [Subscribe](mailto:users-subscribe@eventmesh.apache.org) | [Unsubscribe](mailto:users-unsubscribe@eventmesh.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.apache.org) | [Unsubscribe](mailto:dev-unsubscribe@eventmesh.apache.org) | [Mail Archives](https://lists.apache.org/list.html?dev@eventmesh.apache.org) | +| Commits | Commits to related repositories | [Subscribe](mailto:commits-subscribe@eventmesh.apache.org) | [Unsubscribe](mailto:commits-unsubscribe@eventmesh.apache.org) | [Mail Archives](https://lists.apache.org/list.html?commits@eventmesh.apache.org) | +| Issues | Issues or PRs comments and reviews | [Subscribe](mailto:issues-subscribe@eventmesh.apache.org) | [Unsubscribe](mailto:issues-unsubscribe@eventmesh.apache.org) | [Mail Archives](https://lists.apache.org/list.html?issues@eventmesh.apache.org) | diff --git a/README.zh-CN.md b/README.zh-CN.md index d5febb2655..a134536b1a 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -61,23 +61,121 @@ Apache EventMesh提供了许多功能来帮助用户实现他们的目标,以 - [EventMesh-catalog](https://github.com/apache/eventmesh-catalog): 使用 AsyncAPI 进行事件模式管理的目录服务。 - [EventMesh-go](https://github.com/apache/eventmesh-go): EventMesh 运行时的 Go 语言实现。 -## 快速开始 +## 快速入门 -指南: +本节指南将指导您分别从[本地](#在本地运行-eventmesh-runtime)、[Docker](#在-docker-中运行-eventmesh-runtime)、[K8s](#在-kubernetes-中运行-eventmesh-runtime)部署EventMesh的步骤: -[第1步: 部署EventMesh Store](https://eventmesh.apache.org/docs/instruction/store) +本节指南按照默认配置启动 EventMesh,如果您需要更加详细的 EventMesh 部署步骤,请访问[EventMesh官方文档](https://eventmesh.apache.org/docs/introduction)。 -[第2步: 启动EventMesh Runtime](https://eventmesh.apache.org/docs/instruction/runtime) +### 部署 Event Store -[第3步: 运行示例](https://eventmesh.apache.org/docs/instruction/demo) +> EventMesh 支持[多种事件存储](https://eventmesh.apache.org/docs/roadmap#event-store-implementation-status),默认存储模式为 `standalone`,不依赖其他事件存储作为层。 -另外,如果您更喜欢使用Docker,则我们还为您提供了Docker版本的指南: +### 在本地运行 EventMesh Runtime -[第1步: 使用Docker部署EventMesh Store](https://eventmesh.apache.org/docs/instruction/store-with-docker) +#### 1. 下载 EventMesh -[第2步: 使用Docker启动EventMesh Runtime](https://eventmesh.apache.org/docs/instruction/runtime-with-docker) +从 [EventMesh Download](https://eventmesh.apache.org/download/) 页面下载最新版本的 Binary Distribution 发行版并解压: -[第3步: 运行示例](https://eventmesh.apache.org/docs/instruction/demo) +```shell +wget https://dlcdn.apache.org/eventmesh/1.10.0/apache-eventmesh-1.10.0-bin.tar.gz +tar -xvzf apache-eventmesh-1.10.0-bin.tar.gz +cd apache-eventmesh-1.10.0 +``` + +#### 2. 运行 EventMesh + +执行 `start.sh` 脚本启动 EventMesh Runtime 服务器。 + +```shell +bash bin/start.sh +``` + +查看输出日志: + +```shell +tail -n 50 -f logs/eventmesh.out +``` + +当日志输出 `server state:RUNNING`,则代表 EventMesh Runtime 启动成功了。 + +停止: + +```shell +bash bin/stop.sh +``` + +脚本打印 `shutdown server ok!` 时,代表 EventMesh Runtime 已停止。 + +### 在 Docker 中运行 EventMesh Runtime + +#### 1. 获取 EventMesh 镜像 + +使用下面的命令行下载最新版本的 [EventMesh](https://hub.docker.com/r/apache/eventmesh): + +```shell +sudo docker pull apache/eventmesh:latest +``` + +#### 2. 运行 EventMesh + +使用以下命令启动 EventMesh 容器: + +```shell +sudo docker run -d --name eventmesh -p 10000:10000 -p 10105:10105 -p 10205:10205 -p 10106:10106 -t apache/eventmesh:latest +``` + +进入容器: + +```shell +sudo docker exec -it eventmesh /bin/bash +``` + +查看日志: + +```shell +cd logs +tail -n 50 -f eventmesh.out +``` + +### 在 Kubernetes 中运行 EventMesh Runtime + +#### 1. 部署 Operator + +运行以下命令部署(删除部署, 只需将 `deploy` 替换为 `undeploy` 即可): + +```shell +$ cd eventmesh-operator && make deploy +``` + +运行 `kubectl get pods` 、`kubectl get crd | grep eventmesh-operator.eventmesh` 查看部署的 EventMesh-Operator 状态以及 CRD 信息. + +```shell +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +eventmesh-operator-59c59f4f7b-nmmlm 1/1 Running 0 20s + +$ kubectl get crd | grep eventmesh-operator.eventmesh +connectors.eventmesh-operator.eventmesh 2024-01-10T02:40:27Z +runtimes.eventmesh-operator.eventmesh 2024-01-10T02:40:27Z +``` + +#### 2. 部署 EventMesh Runtime + +运行以下命令部署 runtime、connector-rocketmq (删除部署, 只需将 `create` 替换为 `delete` 即可): + +```shell +$ make create +``` + +运行 `kubectl get pods` 查看部署是否成功. + +```shell +NAME READY STATUS RESTARTS AGE +connector-rocketmq-0 1/1 Running 0 9s +eventmesh-operator-59c59f4f7b-nmmlm 1/1 Running 0 3m12s +eventmesh-runtime-0-a-0 1/1 Running 0 15s +``` ## 贡献 @@ -110,8 +208,8 @@ Apache EventMesh 的开源协议遵循 [Apache License, Version 2.0](http://www. ## Community -| 微信小助手 | 微信公众号 | Slack | -| ------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------ | +| 微信小助手 | 微信公众号 | Slack | +|---------------------------------------------------------|--------------------------------------------------------|---------------------------------------------------------------------------------------------------------| | | | [加入 Slack ](https://join.slack.com/t/apacheeventmesh/shared_invite/zt-1t1816dli-I0t3OE~IpdYWrZbIWhMbXg) | 双周会议 : [#Tencent meeting](https://meeting.tencent.com/dm/wes6Erb9ioVV) : 346-6926-0133 @@ -120,10 +218,10 @@ Apache EventMesh 的开源协议遵循 [Apache License, Version 2.0](http://www. ### 邮件名单 -| 名称 | 描述 | 订阅 | 取消订阅 | 邮件列表存档 | -| ------- | --------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------ | -| 用户 | 用户支持与用户问题 | [订阅](mailto:users-subscribe@eventmesh.apache.org) | [取消订阅](mailto:users-unsubscribe@eventmesh.apache.org) | [邮件存档](https://lists.apache.org/list.html?users@eventmesh.apache.org) | -| 开发 | 开发相关 (设计文档, Issues等等.) | [订阅](mailto:dev-subscribe@eventmesh.apache.org) | [取消订阅](mailto:dev-unsubscribe@eventmesh.apache.org) | [邮件存档](https://lists.apache.org/list.html?dev@eventmesh.apache.org) | -| Commits | 所有与仓库相关的 commits 信息通知 | [订阅](mailto:commits-subscribe@eventmesh.apache.org) | [取消订阅](mailto:commits-unsubscribe@eventmesh.apache.org) | [邮件存档](https://lists.apache.org/list.html?commits@eventmesh.apache.org) | -| Issues | Issues 或者 PR 提交和代码Review | [订阅](mailto:issues-subscribe@eventmesh.apache.org) | [取消订阅](mailto:issues-unsubscribe@eventmesh.apache.org) | [邮件存档](https://lists.apache.org/list.html?issues@eventmesh.apache.org) | +| 名称 | 描述 | 订阅 | 取消订阅 | 邮件列表存档 | +|---------|--------------------------|-----------------------------------------------------|---------------------------------------------------------|-------------------------------------------------------------------------| +| 用户 | 用户支持与用户问题 | [订阅](mailto:users-subscribe@eventmesh.apache.org) | [取消订阅](mailto:users-unsubscribe@eventmesh.apache.org) | [邮件存档](https://lists.apache.org/list.html?users@eventmesh.apache.org) | +| 开发 | 开发相关 (设计文档, Issues等等.) | [订阅](mailto:dev-subscribe@eventmesh.apache.org) | [取消订阅](mailto:dev-unsubscribe@eventmesh.apache.org) | [邮件存档](https://lists.apache.org/list.html?dev@eventmesh.apache.org) | +| Commits | 所有与仓库相关的 commits 信息通知 | [订阅](mailto:commits-subscribe@eventmesh.apache.org) | [取消订阅](mailto:commits-unsubscribe@eventmesh.apache.org) | [邮件存档](https://lists.apache.org/list.html?commits@eventmesh.apache.org) | +| Issues | Issues 或者 PR 提交和代码Review | [订阅](mailto:issues-subscribe@eventmesh.apache.org) | [取消订阅](mailto:issues-unsubscribe@eventmesh.apache.org) | [邮件存档](https://lists.apache.org/list.html?issues@eventmesh.apache.org) | diff --git a/build.gradle b/build.gradle index eea9d85817..ec8bc4a458 100644 --- a/build.gradle +++ b/build.gradle @@ -21,6 +21,8 @@ import java.util.concurrent.TimeUnit buildscript { repositories { + mavenLocal() + mavenCentral() maven { url "https://maven.aliyun.com/repository/public" } @@ -34,14 +36,15 @@ buildscript { classpath "com.github.spotbugs.snom:spotbugs-gradle-plugin:5.0.14" classpath "io.spring.gradle:dependency-management-plugin:1.0.11.RELEASE" classpath "com.github.jk1:gradle-license-report:1.17" + classpath "com.diffplug.spotless:spotless-plugin-gradle:6.13.0" } } -//Remove doclint warnings that pollute javadoc logs when building with java8 -if(JavaVersion.current().isJava8()){ +// Remove doclint warnings that pollute javadoc logs when building +if (JavaVersion.current().isJava8()) { allprojects { - tasks.withType(Javadoc){ - options.addStringOption('xdoclint:none','-quiet') + tasks.withType(Javadoc) { + options.addStringOption('xdoclint:none', '-quiet') } } } @@ -59,6 +62,7 @@ allprojects { apply plugin: "java-library" apply plugin: 'signing' apply plugin: 'checkstyle' + apply plugin: 'com.diffplug.spotless' [compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8' @@ -84,15 +88,54 @@ allprojects { configDirectory = file("${rootDir}/style") } - checkstyleMain.exclude '**/org/apache/eventmesh/client/grpc/protos**' + checkstyleMain.exclude('**/org/apache/eventmesh/client/grpc/protos**') + .exclude('**/org/apache/eventmesh/common/protocol/grpc/cloudevents**') + .exclude('**/org/apache/eventmesh/connector/openfunction/client/EventMeshGrpcService**') + .exclude('**/org/apache/eventmesh/connector/openfunction/client/CallbackServiceGrpc**') + .exclude('**/org/apache/eventmesh/connector/jdbc/antlr**') dependencies { repositories { + mavenLocal() + mavenCentral() maven { url "https://maven.aliyun.com/repository/public" } } - testImplementation "junit:junit:4.13.2" + testImplementation "org.junit.jupiter:junit-jupiter:5.6.0" + } + + spotless { + enforceCheck false + java { + target project.fileTree(project.projectDir) { + include 'src/*/java/**/*.java' + exclude '**/org/apache/eventmesh/**/protos**' + exclude '**/org/apache/eventmesh/connector/openfunction/client/EventMeshGrpcService**' + exclude '**/org/apache/eventmesh/connector/openfunction/client/CallbackServiceGrpc**' + exclude '**/org/apache/eventmesh/connector/jdbc/antlr**' + exclude '**/org/apache/eventmesh/common/protocol/grpc**' + exclude '**/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/AbstractSnapshotEngine.java' + } + importOrder ('\\#org.apache.eventmesh','\\#org.apache','\\#java','\\#javax','\\#org','\\#io','\\#net','\\#junit','\\#com','\\#lombok', + 'org.apache.eventmesh','org.apache','java','javax','org','io','net','junit','com','lombok') + licenseHeaderFile rootProject.file('style/checkstyle-header1.txt') + eclipse().configFile("${rootDir}/style/task/eventmesh-spotless-formatter.xml") + removeUnusedImports() + } + } + + afterEvaluate { + tasks.forEach {task -> + if (task.name.contains("spotlessJava")) { + task.dependsOn(compileJava, javadoc, compileTestJava, test, processResources, processTestResources) + } + } + spotlessJava.dependsOn(subprojects.collect {it.tasks["spotlessJava"] }) + } + + test { + useJUnitPlatform() } } @@ -242,6 +285,9 @@ subprojects { rulesMinimumPriority = 5 ruleSets = ["category/java/errorprone.xml", "category/java/bestpractices.xml"] ignoreFailures = true + pmdMain { + excludes = ["**/org/apache/eventmesh/connector/jdbc/antlr4/autogeneration/**"] + } } jar { @@ -265,14 +311,12 @@ subprojects { new File("${projectDir}/dist/lib").mkdirs() new File("${projectDir}/dist/licenses").mkdirs() } - Set rootProject = ["eventmesh-admin", - "eventmesh-admin-rocketmq", - "eventmesh-common", - "eventmesh-connector-api", + Set rootProject = ["eventmesh-common", "eventmesh-storage-api", "eventmesh-metrics-api", - "eventmesh-registry-api", + "eventmesh-meta-api", "eventmesh-trace-api", + "eventmesh-retry-api", "eventmesh-runtime", "eventmesh-security-api", "eventmesh-protocol-api", @@ -280,8 +324,7 @@ subprojects { "eventmesh-spi", "eventmesh-webhook-api", "eventmesh-webhook-admin", - "eventmesh-webhook-receive" - ] + "eventmesh-webhook-receive"] doLast { copy { into("${projectDir}/dist/apps") @@ -334,6 +377,7 @@ subprojects { javadoc { source = sourceSets.main.java destinationDir = reporting.file("javadoc") + options.encoding = "UTF-8" } task packageJavadoc(type: Jar, dependsOn: ['javadoc']) { @@ -361,9 +405,9 @@ subprojects { } repositories { - maven { url "https://maven.aliyun.com/repository/public" } - mavenCentral() mavenLocal() + mavenCentral() + maven { url "https://maven.aliyun.com/repository/public" } } configurations.all { @@ -392,7 +436,7 @@ subprojects { licenses { license { name = 'The Apache License, Version 2.0' - url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + url = 'https://www.apache.org/licenses/LICENSE-2.0.txt' } } developers { @@ -429,6 +473,7 @@ subprojects { } def grpcVersion = '1.43.2' + def log4jVersion = '2.22.1' dependencyManagement { dependencies { @@ -438,12 +483,15 @@ subprojects { dependency "commons-io:commons-io:2.11.0" + dependency "commons-validator:commons-validator:1.7" + 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 "org.slf4j:slf4j-api:2.0.9" + dependency "org.apache.logging.log4j:log4j-api:${log4jVersion}" + dependency "org.apache.logging.log4j:log4j-core:${log4jVersion}" + dependency "org.apache.logging.log4j:log4j-slf4j2-impl:${log4jVersion}" + dependency "org.apache.logging.log4j:log4j-slf4j-impl:${log4jVersion}" // used with SLF4J 1.7.x or older for third-party dependencies dependency "com.lmax:disruptor:3.4.2" @@ -451,6 +499,9 @@ subprojects { dependency "com.fasterxml.jackson.core:jackson-core:2.13.0" dependency "com.fasterxml.jackson.core:jackson-annotations:2.13.0" dependency "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.0" + dependency "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.0" + + dependency "com.squareup.okhttp3:okhttp:3.14.9" dependency "org.asynchttpclient:async-http-client:2.12.0" dependency "org.apache.httpcomponents:httpclient:4.5.13" @@ -476,22 +527,24 @@ subprojects { dependency "com.h3xstream.findsecbugs:findsecbugs-plugin:1.11.0" dependency "com.mebigfatguy.fb-contrib:fb-contrib:7.6.0" + dependency "com.jayway.jsonpath:json-path:2.7.0" dependency "org.springframework.boot:spring-boot-starter-web:2.7.10" 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.junit.jupiter:junit-jupiter:5.6.0" + dependency "org.junit-pioneer:junit-pioneer:1.9.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.9" + dependency "org.mockito:mockito-junit-jupiter:3.8.0" - dependency "io.cloudevents:cloudevents-core:2.2.0" - dependency "io.cloudevents:cloudevents-json-jackson:2.2.0" + dependency "io.cloudevents:cloudevents-core:2.4.2" + dependency "io.cloudevents:cloudevents-json-jackson:2.4.2" + dependency "io.cloudevents:cloudevents-protobuf:2.4.2" + dependency "io.grpc:grpc-core:${grpcVersion}" dependency "io.grpc:grpc-protobuf:${grpcVersion}" dependency "io.grpc:grpc-stub:${grpcVersion}" dependency "io.grpc:grpc-netty:${grpcVersion}" @@ -517,6 +570,10 @@ subprojects { dependency "com.github.seancfoley:ipaddress:5.3.3" dependency "javax.annotation:javax.annotation-api:1.3.2" dependency "com.alibaba:fastjson:1.2.83" + + dependency "software.amazon.awssdk:s3:2.20.29" + dependency "com.github.rholder:guava-retrying:2.0.0" + } } } diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 14b76af876..0000000000 --- a/docker/Dockerfile +++ /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. -# -FROM openjdk:8-jdk as builder -WORKDIR /build -COPY . . -RUN ./gradlew clean build jar dist --parallel --daemon -RUN ./gradlew installPlugin - -FROM openjdk:8-jdk -RUN apt-get update && apt-get install -y locales -RUN localedef -i en_US -f UTF-8 en_US.UTF-8 --quiet -WORKDIR /data/app/eventmesh -COPY --from=builder /build/dist ./ - -EXPOSE 10106 -EXPOSE 10205 10105 10002 - -ENV DOCKER true -ENV EVENTMESH_HOME /data/app/eventmesh -ENV EVENTMESH_LOG_HOME /data/app/eventmesh/logs -ENV CONFPATH /data/app/eventmesh/conf - -CMD ["bash", "bin/start.sh"] diff --git a/docker/Dockerfile_jdk11 b/docker/Dockerfile_jdk11 new file mode 100644 index 0000000000..95eaeb9851 --- /dev/null +++ b/docker/Dockerfile_jdk11 @@ -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. +# +FROM openjdk:11-jdk as builder +WORKDIR /build +COPY . . +RUN ./gradlew clean build dist --parallel --daemon +RUN ./gradlew installPlugin + +FROM openjdk:11-jdk +RUN apt-get update && apt-get install -y locales procps +RUN localedef -i en_US -f UTF-8 en_US.UTF-8 --quiet +WORKDIR /data/app/eventmesh +COPY --from=builder /build/dist ./ + +EXPOSE 10000 10105 10106 10205 + +ENV DOCKER true +ENV EVENTMESH_HOME /data/app/eventmesh +ENV EVENTMESH_LOG_HOME /data/app/eventmesh/logs +ENV CONFPATH /data/app/eventmesh/conf + +CMD ["bash", "bin/start.sh"] diff --git a/docker/Dockerfile_jdk8 b/docker/Dockerfile_jdk8 new file mode 100644 index 0000000000..78c16290f5 --- /dev/null +++ b/docker/Dockerfile_jdk8 @@ -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. +# +FROM openjdk:11-jdk as builder_11 +WORKDIR /build +COPY . . +RUN ./gradlew clean generateGrammarSource --parallel --daemon + +FROM openjdk:8-jdk as builder_8 +WORKDIR /build +COPY --from=builder_11 /build ./ +RUN ./gradlew clean build dist -x spotlessJava -x generateGrammarSource --parallel --daemon +RUN ./gradlew installPlugin + +FROM openjdk:8-jdk +RUN apt-get update && apt-get install -y locales procps +RUN localedef -i en_US -f UTF-8 en_US.UTF-8 --quiet +WORKDIR /data/app/eventmesh +COPY --from=builder_8 /build/dist ./ + +EXPOSE 10000 10105 10106 10205 + +ENV DOCKER true +ENV EVENTMESH_HOME /data/app/eventmesh +ENV EVENTMESH_LOG_HOME /data/app/eventmesh/logs +ENV CONFPATH /data/app/eventmesh/conf + +CMD ["bash", "bin/start.sh"] diff --git a/eventmesh-admin/README.md b/eventmesh-admin/README.md deleted file mode 100644 index 69db9bb59a..0000000000 --- a/eventmesh-admin/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# 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/eventmesh-admin-rocketmq/build.gradle b/eventmesh-admin/eventmesh-admin-rocketmq/build.gradle deleted file mode 100644 index ff0fc04eb8..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/build.gradle +++ /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. - */ - - -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-storage-plugin:eventmesh-storage-api") - - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - - testImplementation project(":eventmesh-storage-plugin:eventmesh-storage-api") -} diff --git a/eventmesh-admin/eventmesh-admin-rocketmq/gradle.properties b/eventmesh-admin/eventmesh-admin-rocketmq/gradle.properties deleted file mode 100644 index fd11b473bf..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/gradle.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. -# - -rocketmq_version=4.9.5 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 deleted file mode 100644 index 9a61dee92d..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/Constants.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 org.apache.eventmesh.admin.rocketmq; - -public class Constants { - - public static final String TOPIC_MANAGE_PATH = "/topicManage"; - - public static final String CONTENT_TYPE = "Content-Type"; - - public static final String APPLICATION_JSON = "application/json"; - - public static final String TOPIC_ERROR = "create topic failed! Server side error"; -} 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 deleted file mode 100644 index 573a0c3661..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/controller/AdminController.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 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 com.sun.net.httpserver.HttpServer; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class AdminController { - - public AdminController() { - } - - public void run(HttpServer server) throws IOException { - - server.createContext(TOPIC_MANAGE_PATH, new TopicsHandler()); - - log.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 deleted file mode 100644 index c0aa2c7c19..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/handler/TopicsHandler.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.admin.rocketmq.handler; - -import static org.apache.eventmesh.admin.rocketmq.Constants.APPLICATION_JSON; -import static org.apache.eventmesh.admin.rocketmq.Constants.CONTENT_TYPE; -import static org.apache.eventmesh.admin.rocketmq.Constants.TOPIC_ERROR; -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.RequestMapping; -import org.apache.eventmesh.common.Constants; -import org.apache.eventmesh.common.utils.JsonUtils; -import org.apache.eventmesh.common.utils.NetUtils; - -import org.apache.commons.lang3.StringUtils; - -import java.io.IOException; -import java.io.OutputStream; - -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class TopicsHandler implements HttpHandler { - - @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: %s", httpExchange.getRequestURI()); - log.error(result); - out.write(result.getBytes(Constants.DEFAULT_CHARSET)); - } - - public void createTopicHandler(HttpExchange httpExchange) throws IOException { - String result; - try (OutputStream out = httpExchange.getResponseBody()) { - String params = NetUtils.parsePostBody(httpExchange); - TopicCreateRequest topicCreateRequest = - JsonUtils.parseObject(params, TopicCreateRequest.class); - String topic = topicCreateRequest.getName(); - - if (StringUtils.isBlank(topic)) { - result = "Create topic failed. Parameter topic not found."; - log.error(result); - out.write(result.getBytes(Constants.DEFAULT_CHARSET)); - return; - } - - //TBD: A new rocketmq service will be implemented for creating topics - TopicResponse topicResponse = null; - if (topicResponse != null) { - log.info("create a new topic: {}", topic); - httpExchange.getResponseHeaders().add(CONTENT_TYPE, APPLICATION_JSON); - NetUtils.sendSuccessResponseHeaders(httpExchange); - result = JsonUtils.toJSONString(topicResponse); - log.info(result); - out.write(result.getBytes(Constants.DEFAULT_CHARSET)); - } else { - httpExchange.sendResponseHeaders(500, 0); - result = TOPIC_ERROR; - log.error(result); - out.write(result.getBytes(Constants.DEFAULT_CHARSET)); - } - } catch (Exception e) { - httpExchange.getResponseHeaders().add(CONTENT_TYPE, APPLICATION_JSON); - httpExchange.sendResponseHeaders(500, 0); - result = TOPIC_ERROR; - log.error(result, 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 deleted file mode 100644 index 7adaa77cd2..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/request/TopicCreateRequest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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 deleted file mode 100644 index 9ccdc2bb85..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/response/TopicResponse.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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=").append(this.topic).append(",").append("created_time=").append(this.createdTime).append("}"); - return sb.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 deleted file mode 100644 index e796e49edc..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/RequestMapping.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 org.apache.eventmesh.admin.rocketmq.util; - -import org.apache.eventmesh.common.enums.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 deleted file mode 100644 index 199e417299..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/src/main/java/org/apache/eventmesh/admin/rocketmq/util/UrlMappingPattern.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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/eventmesh-admin-rocketmq/src/test/java/org/apache/eventmesh/admin/rocketmq/response/TopicResponseTest.java b/eventmesh-admin/eventmesh-admin-rocketmq/src/test/java/org/apache/eventmesh/admin/rocketmq/response/TopicResponseTest.java deleted file mode 100644 index 311dc6efcf..0000000000 --- a/eventmesh-admin/eventmesh-admin-rocketmq/src/test/java/org/apache/eventmesh/admin/rocketmq/response/TopicResponseTest.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 org.apache.eventmesh.admin.rocketmq.response; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.fasterxml.jackson.databind.ObjectMapper; - -public class TopicResponseTest { - - @Test - public void testTopicResponse() { - String topic = "testtopic"; - String createdTime = "2023-05-17 10:30:00"; - TopicResponse topicResponse = new TopicResponse(topic, createdTime); - - assertEquals(topic, topicResponse.getTopic()); - assertEquals(createdTime, topicResponse.getCreatedTime()); - } - - @Test - public void testTopicResponseSerialization() throws Exception { - String topic = "testtopic"; - String createdTime = "2023-05-17 10:30:00"; - TopicResponse topicResponse = new TopicResponse(topic, createdTime); - - ObjectMapper objectMapper = new ObjectMapper(); - String json = objectMapper.writeValueAsString(topicResponse); - - assertTrue(json.contains("topic")); - assertTrue(json.contains("created_time")); - - TopicResponse deserializedResponse = objectMapper.readValue(json, TopicResponse.class); - - assertEquals(topic, deserializedResponse.getTopic()); - assertEquals(createdTime, deserializedResponse.getCreatedTime()); - } -} diff --git a/eventmesh-common/build.gradle b/eventmesh-common/build.gradle index c4f6e5e4d1..fd7a6e1ee6 100644 --- a/eventmesh-common/build.gradle +++ b/eventmesh-common/build.gradle @@ -15,7 +15,7 @@ * limitations under the License. */ -def grpcVersion = '1.42.2' +def grpcVersion = '1.43.2' dependencies { api "com.google.guava:guava" @@ -25,9 +25,14 @@ dependencies { api "org.apache.commons:commons-text" api "org.apache.commons:commons-lang3" + api "com.jayway.jsonpath:json-path" + + api "io.cloudevents:cloudevents-core" + api "io.cloudevents:cloudevents-json-jackson" + implementation "org.apache.logging.log4j:log4j-api" implementation "org.apache.logging.log4j:log4j-core" - implementation "org.apache.logging.log4j:log4j-slf4j-impl" + implementation "org.apache.logging.log4j:log4j-slf4j2-impl" implementation 'com.github.seancfoley:ipaddress' @@ -36,6 +41,7 @@ dependencies { api "com.fasterxml.jackson.core:jackson-databind" api "com.fasterxml.jackson.core:jackson-core" api "com.fasterxml.jackson.core:jackson-annotations" + api "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" implementation "org.apache.httpcomponents:httpclient" @@ -45,7 +51,7 @@ dependencies { implementation "io.grpc:grpc-stub:${grpcVersion}" implementation "javax.annotation:javax.annotation-api:1.3.2" - implementation "com.github.stefanbirkner:system-rules" + testImplementation "org.junit-pioneer:junit-pioneer" implementation "org.yaml:snakeyaml" compileOnly 'org.projectlombok:lombok' @@ -61,7 +67,7 @@ dependencies { 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 "org.apache.logging.log4j:log4j-slf4j2-impl" testImplementation "com.lmax:disruptor" @@ -76,6 +82,5 @@ dependencies { testImplementation "org.assertj:assertj-core" testImplementation "org.mockito:mockito-core" - testImplementation "org.powermock:powermock-module-junit4" - testImplementation "org.powermock:powermock-api-mockito2" + testImplementation "org.mockito:mockito-junit-jupiter" } 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 index cc76f55f8b..867d50b43b 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/Constants.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/Constants.java @@ -32,6 +32,8 @@ public class Constants { public static final String LANGUAGE_JAVA = "JAVA"; + public static final String CONNECT_SERVER_CONFIG_FILE_NAME = "server-config.yml"; + public static final String HTTP_PROTOCOL_PREFIX = "http://"; public static final String HTTPS_PROTOCOL_PREFIX = "https://"; @@ -126,11 +128,11 @@ public class Constants { public static final String OPERATION_TIMEOUT = "OPERATION_TIMEOUT"; - public static String CLOUD_EVENTS_PROTOCOL_NAME = "cloudevents"; + public static final String CLOUD_EVENTS_PROTOCOL_NAME = "cloudevents"; - public static String EM_MESSAGE_PROTOCOL_NAME = "eventmeshmessage"; + public static final String EM_MESSAGE_PROTOCOL_NAME = "eventmeshmessage"; - public static String OPEN_MESSAGE_PROTOCOL_NAME = "openmessage"; + public static final String OPEN_MESSAGE_PROTOCOL_NAME = "openmessage"; // delimiter define public static final String COMMA = ","; @@ -149,6 +151,8 @@ public class Constants { public static final String UNDER_LINE = "_"; + public static final String UNKNOWN = "unknown"; + public static final String LEFT_PARENTHESIS = "("; public static final String RIGHT_PARENTHESIS = ")"; @@ -169,6 +173,17 @@ public class Constants { public static final int SUCCESS_CODE = 200; + public static final String SINK = "Sink"; + + public static final String SOURCE = "Source"; + + // protocol desc + public static final String PROTOCOL_DESC_GRPC_CLOUD_EVENT = "grpc-cloud-event"; + + public static final String PROTOCOL_DESC_HTTP = "http"; + + public static final String PROTOCOL_DESC_TCP = "tcp"; + /** * GRPC PROTOCOL */ @@ -178,4 +193,16 @@ public class Constants { * application/cloudevents+json Content-type */ public static final String CONTENT_TYPE_CLOUDEVENTS_JSON = "application/cloudevents+json"; + + public static final String HTTP = "HTTP"; + + public static final String TCP = "TCP"; + + public static final String GRPC = "GRPC"; + + public static final String OS_NAME_KEY = "os.name"; + + public static final String OS_WIN_PREFIX = "win"; + + public static final String DEFAULT = "default"; } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/ResetCountDownLatch.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/ResetCountDownLatch.java new file mode 100644 index 0000000000..bb6a01f976 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/ResetCountDownLatch.java @@ -0,0 +1,178 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.TimeUnit; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +/** + * ResetCountDownLatch can reset + * + * @see java.util.concurrent.CountDownLatch + */ +public class ResetCountDownLatch { + + private final RestSync restSync; + + public ResetCountDownLatch(int count) { + this.restSync = new RestSync(count); + } + + /** + * Causes the current thread to wait until the latch has counted down to zero, unless the thread is {@linkplain Thread#interrupt interrupted}. + * + *

If the current count is zero then this method returns immediately. + * + *

If the current count is greater than zero then the current + * thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happen: + *

    + *
  • The count reaches zero due to invocations of the + * {@link #countDown} method; or + *
  • Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread. + *
+ * + *

If the current thread: + *

    + *
  • has its interrupted status set on entry to this method; or + *
  • is {@linkplain Thread#interrupt interrupted} while waiting, + *
+ * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * @throws InterruptedException if the current thread is interrupted while waiting + */ + public void await() throws InterruptedException { + restSync.acquireSharedInterruptibly(1); + } + + /** + * Causes the current thread to wait until the latch has counted down to zero, unless the thread is {@linkplain Thread#interrupt interrupted}, or + * the specified waiting time elapses. + * + *

If the current count is zero then this method returns immediately + * with the value {@code true}. + * + *

If the current count is greater than zero then the current + * thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happen: + *

    + *
  • The count reaches zero due to invocations of the + * {@link #countDown} method; or + *
  • Some other thread {@linkplain Thread#interrupt interrupts} + * the current thread; or + *
  • The specified waiting time elapses. + *
+ * + *

If the count reaches zero then the method returns with the + * value {@code true}. + * + *

If the current thread: + *

    + *
  • has its interrupted status set on entry to this method; or + *
  • is {@linkplain Thread#interrupt interrupted} while waiting, + *
+ * then {@link InterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + *

If the specified waiting time elapses then the value {@code false} + * is returned. If the time is less than or equal to zero, the method + * will not wait at all. + * + * @param timeout the maximum time to wait + * @param unit the time unit of the {@code timeout} argument + * @return {@code true} if the count reached zero and {@code false} if the waiting time elapsed before the count reached zero + * @throws InterruptedException if the current thread is interrupted while waiting + */ + public boolean await(long timeout, TimeUnit unit) + throws InterruptedException { + return restSync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); + } + + /** + * Decrements the count of the latch, releasing all waiting threads if the count reaches zero. + * + *

If the current count is greater than zero then it is decremented. + * If the new count is zero then all waiting threads are re-enabled for thread scheduling purposes. + * + *

If the current count equals zero then nothing happens. + */ + public void countDown() { + restSync.releaseShared(1); + } + + /** + * Returns the current count. + * + *

This method is typically used for debugging and testing purposes. + * + * @return the current count + */ + public int getCount() { + return restSync.getCount(); + } + + /** + * Reset the CountDownLatch + */ + public void reset() { + restSync.reset(); + } + + /** + * Synchronization control For ResetCountDownLatch. Uses AQS state to represent count. + */ + private static final class RestSync extends AbstractQueuedSynchronizer { + + private final int initCount; + + RestSync(int count) { + if (count < 0) { + throw new IllegalArgumentException("count must be greater than or equal to 0"); + } + this.initCount = count; + setState(count); + } + + protected void reset() { + setState(initCount); + } + + int getCount() { + return getState(); + } + + @Override + protected int tryAcquireShared(int acquires) { + return (getState() == 0) ? 1 : -1; + } + + @Override + protected boolean tryReleaseShared(int releases) { + for (;;) { + int count = getState(); + if (count == 0) { + return false; + } + int nextCount = count - 1; + if (compareAndSetState(count, nextCount)) { + return nextCount == 0; + } + } + } + } +} 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 index 551d92c9ae..7b1cc6d948 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/ThreadPoolFactory.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/ThreadPoolFactory.java @@ -54,7 +54,6 @@ public static ScheduledExecutorService createSingleScheduledExecutor(final Strin return Executors.newSingleThreadScheduledExecutor(new EventMeshThreadFactory(threadName, true)); } - 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/ThreadWrapper.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/ThreadWrapper.java new file mode 100644 index 0000000000..b24402c5fe --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/ThreadWrapper.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.common; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class ThreadWrapper implements Runnable { + + private final AtomicBoolean started = new AtomicBoolean(false); + protected Thread thread; + protected final ResetCountDownLatch waiter = new ResetCountDownLatch(1); + protected volatile AtomicBoolean hasWakeup = new AtomicBoolean(false); + protected boolean isDaemon = false; + protected volatile boolean isRunning = false; + + public ThreadWrapper() { + + } + + public abstract String getThreadName(); + + public void start() { + + if (!started.compareAndSet(false, true)) { + log.warn("Start thread:{} fail", getThreadName()); + return; + } + this.thread = new Thread(this, getThreadName()); + this.thread.setDaemon(isDaemon); + this.thread.start(); + this.isRunning = true; + log.info("Start thread:{} success", getThreadName()); + } + + public void await() { + if (hasWakeup.compareAndSet(true, false)) { + return; + } + // reset count + waiter.reset(); + try { + waiter.await(); + } catch (InterruptedException e) { + log.error("Thread[{}] Interrupted", getThreadName(), e); + } finally { + hasWakeup.set(false); + } + } + + public void await(long timeout) { + await(timeout, TimeUnit.MILLISECONDS); + } + + public void await(long timeout, TimeUnit timeUnit) { + if (hasWakeup.compareAndSet(true, false)) { + return; + } + // reset count + waiter.reset(); + try { + waiter.await(timeout, timeUnit == null ? TimeUnit.MILLISECONDS : timeUnit); + } catch (InterruptedException e) { + log.error("Thread[{}] Interrupted", getThreadName(), e); + } finally { + hasWakeup.set(false); + } + } + + public void wakeup() { + if (hasWakeup.compareAndSet(false, true)) { + waiter.countDown(); + } + } + + public void shutdownImmediately() { + shutdown(true); + } + + public void shutdown() { + shutdown(false); + } + + private void shutdown(final boolean interruptThread) { + if (!started.compareAndSet(true, false)) { + return; + } + this.isRunning = false; + // wakeup the thread to run + wakeup(); + + try { + if (interruptThread) { + this.thread.interrupt(); + } + if (!this.isDaemon) { + // wait main thread to wait this thread finish + this.thread.join(TimeUnit.SECONDS.toMillis(60)); + } + } catch (InterruptedException e) { + log.error("Thread[{}] Interrupted", getThreadName(), e); + } + } + + public void setDaemon(boolean daemon) { + isDaemon = daemon; + } + + public boolean isStated() { + return this.started.get(); + } +} 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 index 61e4d9ac61..338edf3536 100644 --- 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 @@ -17,7 +17,9 @@ package org.apache.eventmesh.common.config; -import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import static org.apache.eventmesh.common.Constants.HTTP; + +import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.utils.IPUtils; import org.apache.commons.collections4.CollectionUtils; @@ -53,9 +55,26 @@ public class CommonConfiguration { @ConfigFiled(field = "server.hostIp", reload = true) private String eventMeshServerIp = null; - @ConfigFiled(field = "registry.plugin.server-addr", notEmpty = true) - private String namesrvAddr = ""; + @ConfigFiled(field = "metaStorage.plugin.server-addr", notEmpty = true) + private String metaStorageAddr = ""; + + @ConfigFiled(field = "metaStorage.plugin.type", notEmpty = true) + private String eventMeshMetaStoragePluginType = "nacos"; + + @ConfigFiled(field = "metaStorage.plugin.username") + private String eventMeshMetaStoragePluginUsername = ""; + + @ConfigFiled(field = "metaStorage.plugin.password") + private String eventMeshMetaStoragePluginPassword = ""; + @ConfigFiled(field = "metaStorage.plugin.metaStorageIntervalInMills") + private Integer eventMeshMetaStorageIntervalInMills = 10 * 1000; + + @ConfigFiled(field = "metaStorage.plugin.fetchMetaStorageAddrIntervalInMills") + private Integer eventMeshFetchMetaStorageAddrInterval = 10 * 1000; + + @ConfigFiled(field = "metaStorage.plugin.enabled") + private boolean eventMeshServerMetaStorageEnable = false; @ConfigFiled(field = "trace.plugin", notEmpty = true) private String eventMeshTracePluginType; @@ -63,9 +82,6 @@ public class CommonConfiguration { @ConfigFiled(field = "metrics.plugin", notEmpty = true) private List eventMeshMetricsPluginType; - @ConfigFiled(field = "registry.plugin.type", notEmpty = true) - private String eventMeshRegistryPluginType = "namesrv"; - @ConfigFiled(field = "security.plugin.type", notEmpty = true) private String eventMeshSecurityPluginType = "security"; @@ -78,41 +94,27 @@ public class CommonConfiguration { @ConfigFiled(field = "security.validation.type.token", notEmpty = true) private boolean eventMeshSecurityValidateTypeToken = false; - @ConfigFiled(field = "registry.plugin.username") - private String eventMeshRegistryPluginUsername = ""; - - @ConfigFiled(field = "registry.plugin.password") - private String eventMeshRegistryPluginPassword = ""; - - @ConfigFiled(field = "server.registry.registerIntervalInMills") - private Integer eventMeshRegisterIntervalInMills = 10 * 1000; - - @ConfigFiled(field = "server.registry.fetchRegistryAddrIntervalInMills") - private Integer eventMeshFetchRegistryAddrInterval = 10 * 1000; - - @ConfigFiled(field = "server.trace.enabled") private boolean eventMeshServerTraceEnable = false; @ConfigFiled(field = "server.security.enabled") private boolean eventMeshServerSecurityEnable = false; - @ConfigFiled(field = "server.registry.enabled") - private boolean eventMeshServerRegistryEnable = false; - @ConfigFiled(field = "security.publickey") private String eventMeshSecurityPublickey = ""; @ConfigFiled(field = "server.provide.protocols", reload = true) private List eventMeshProvideServerProtocols; - @ConfigFiled(reload = true) private String eventMeshWebhookOrigin; @ConfigFiled(reload = true) private String meshGroup; + @ConfigFiled(field = "server.retry.plugin.type") + private String eventMeshRetryPluginType = Constants.DEFAULT; + public void reload() { this.eventMeshWebhookOrigin = "eventmesh." + eventMeshIDC; @@ -121,9 +123,9 @@ public void reload() { } if (CollectionUtils.isEmpty(eventMeshProvideServerProtocols)) { - this.eventMeshProvideServerProtocols = Collections.singletonList(ConfigurationContextUtil.HTTP); + this.eventMeshProvideServerProtocols = Collections.singletonList(HTTP); } - meshGroup = String.join("-", this.eventMeshEnv, this.eventMeshCluster, this.sysID); + meshGroup = String.join("-", this.eventMeshEnv, this.eventMeshIDC, this.eventMeshCluster, this.sysID); } } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/Config.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/Config.java index db16c96d7c..6c6d726525 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/Config.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/Config.java @@ -52,6 +52,3 @@ Config[] value(); } } - - - diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigService.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigService.java index 4b938b16c1..7c5b17d7e6 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigService.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/ConfigService.java @@ -17,6 +17,8 @@ package org.apache.eventmesh.common.config; +import static org.apache.eventmesh.common.utils.ReflectUtils.lookUpFieldByParentClass; + import org.apache.commons.lang3.StringUtils; import java.io.File; @@ -27,7 +29,6 @@ import java.util.Objects; import java.util.Properties; - import org.assertj.core.util.Strings; import lombok.Getter; @@ -155,7 +156,15 @@ private void populateConfig(Object object, Class clazz, Config config) configInfo.setMonitor(config.monitor()); configInfo.setReloadMethodName(config.reloadMethodName()); - Field field = clazz.getDeclaredField(configInfo.getField()); + Field field = null; + try { + field = clazz.getDeclaredField(configInfo.getField()); + } catch (NoSuchFieldException e) { + field = lookUpFieldByParentClass(clazz, configInfo.getField()); + if (field == null) { + throw e; + } + } configInfo.setClazz(field.getType()); Config configType = field.getType().getAnnotation(Config.class); @@ -180,4 +189,5 @@ private void populateConfig(Object object, Class clazz, Config config) configMonitorService.monitor(configInfo); } } + } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/FileLoad.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/FileLoad.java index 80cbf72a57..adfdc9f581 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/FileLoad.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/FileLoad.java @@ -44,9 +44,9 @@ public interface FileLoad { YamlFileLoad YAML_FILE_LOAD = new YamlFileLoad(); static FileLoad getFileLoad(String fileType) { - if (Objects.equals("properties", fileType)) { + if (StringUtils.equals("properties", fileType)) { return PROPERTIES_FILE_LOAD; - } else if (Objects.equals("yaml", fileType)) { + } else if (StringUtils.equals("yaml", fileType)) { return YAML_FILE_LOAD; } return PROPERTIES_FILE_LOAD; diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConverterMap.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConverterMap.java index 3f59730c95..1fa1bced57 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConverterMap.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/ConverterMap.java @@ -47,7 +47,6 @@ import java.util.TreeMap; import java.util.Vector; - import lombok.extern.slf4j.Slf4j; import inet.ipaddr.IPAddress; diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/BaseDataTypeConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/BaseDataTypeConverter.java index 053580c46f..fac41fea13 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/BaseDataTypeConverter.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/BaseDataTypeConverter.java @@ -42,7 +42,7 @@ public static class BooleanConverter implements ConvertValue { @Override public Boolean convert(ConvertInfo convertInfo) { String value = (String) convertInfo.getValue(); - if (Objects.equals(value.length(), 1)) { + if (value.length() == 1) { return Objects.equals(convertInfo.getValue(), "1") ? Boolean.TRUE : Boolean.FALSE; } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ListConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ListConverter.java index 1627b34324..3d0e92e9c9 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ListConverter.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ListConverter.java @@ -79,7 +79,6 @@ public List convert(ConvertInfo convertInfo, String separator) { } } - public static class ListConverterSemi extends ListConverter { public String separator = ";"; diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ObjectConverter.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ObjectConverter.java index e1f860c5e5..6e118851e2 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ObjectConverter.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/config/convert/converter/ObjectConverter.java @@ -71,7 +71,7 @@ public Object convert(ConvertInfo convertInfo) { this.setValue(); Class superclass = convertInfo.getClazz(); - for (; ; ) { + for (;;) { superclass = superclass.getSuperclass(); if (Objects.equals(superclass, Object.class) || Objects.isNull(superclass)) { break; diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/enums/ConnectionType.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/enums/ConnectionType.java new file mode 100644 index 0000000000..ce7e062a54 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/enums/ConnectionType.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.common.enums; + +public enum ConnectionType { + PERSISTENT, + SHORT_LIVED +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/enums/EventMeshDataContentType.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/enums/EventMeshDataContentType.java new file mode 100644 index 0000000000..05341c96b8 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/enums/EventMeshDataContentType.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.common.enums; + +import lombok.Getter; + +public enum EventMeshDataContentType { + + JSON("application/json"); + + @Getter + private String code; + + EventMeshDataContentType(String code) { + this.code = code; + } + +} 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 index 4adafcb4a7..39728b3f90 100644 --- 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 @@ -19,7 +19,7 @@ public class EventMeshException extends RuntimeException { - public static final long serialVersionUID = 5648256502005456586L; + private static final long serialVersionUID = 5648256502005456586L; public EventMeshException(String message) { super(message); 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 index 4f72b20e88..77dd5cf981 100644 --- 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 @@ -21,7 +21,6 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -61,14 +60,10 @@ private static void shutdown() { return; } - if (log.isInfoEnabled()) { - log.info("[WatchFileManager] start close"); - } + log.info("[WatchFileManager] start close"); for (Map.Entry entry : WATCH_FILE_TASK_MAP.entrySet()) { - if (log.isInfoEnabled()) { - log.info("[WatchFileManager] start to shutdown : {}", entry.getKey()); - } + log.info("[WatchFileManager] start to shutdown : {}", entry.getKey()); try { entry.getValue().shutdown(); 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 index 5d7ea3088a..3de204e3db 100644 --- 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 @@ -17,6 +17,7 @@ package org.apache.eventmesh.common.file; +import java.io.IOException; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Path; @@ -28,7 +29,6 @@ import java.util.ArrayList; import java.util.List; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -54,11 +54,21 @@ public WatchFileTask(String directoryPath) { throw new IllegalArgumentException("must be a file directory : " + directoryPath); } - try (WatchService watchService = FILE_SYSTEM.newWatchService()) { - this.watchService = watchService; + try { + this.watchService = FILE_SYSTEM.newWatchService(); + } catch (IOException ex) { + throw new RuntimeException("WatchService initialization fail", ex); + } + + try { path.register(this.watchService, StandardWatchEventKinds.OVERFLOW, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE); - } catch (Exception ex) { + } catch (IOException ex) { + try { + this.watchService.close(); + } catch (IOException e) { + ex.addSuppressed(e); + } throw new UnsupportedOperationException("WatchService registry fail", ex); } } @@ -71,6 +81,11 @@ public void addFileChangeListener(FileChangeListener fileChangeListener) { public void shutdown() { watch = false; + try { + this.watchService.close(); + } catch (IOException e) { + throw new RuntimeException("Unable to close WatchService", e); + } } @Override @@ -88,9 +103,7 @@ public void run() { for (WatchEvent event : events) { WatchEvent.Kind kind = event.kind(); if (kind.equals(StandardWatchEventKinds.OVERFLOW)) { - if (log.isWarnEnabled()) { - log.warn("[WatchFileTask] file overflow: {}", event.context()); - } + log.warn("[WatchFileTask] file overflow: {}", event.context()); continue; } precessWatchEvent(event); @@ -98,9 +111,7 @@ public void run() { } catch (InterruptedException ex) { boolean interrupted = Thread.interrupted(); if (interrupted) { - if (log.isDebugEnabled()) { - log.debug("[WatchFileTask] file watch is interrupted"); - } + log.debug("[WatchFileTask] file watch is interrupted"); } } catch (Exception ex) { log.error("[WatchFileTask] an exception occurred during file listening : ", ex); 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 index 8502bb0cdf..61df341383 100644 --- 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 @@ -18,6 +18,7 @@ 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"); 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 index a2b040f957..5c4dbacee8 100644 --- 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 @@ -22,7 +22,6 @@ import java.util.List; import java.util.concurrent.ThreadLocalRandom; - import lombok.extern.slf4j.Slf4j; /** 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 index 82a35fb562..89befd6d30 100644 --- 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 @@ -41,7 +41,6 @@ public void increaseCurrentWeight() { currentWeight.addAndGet(value); } - public T getTarget() { return target; } @@ -54,7 +53,6 @@ public int getValue() { return value; } - public AtomicInteger getCurrentWeight() { return currentWeight; } 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 index a65425aa6f..7557b3dc2d 100644 --- 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 @@ -21,7 +21,6 @@ import java.util.List; - import lombok.extern.slf4j.Slf4j; /** @@ -45,7 +44,6 @@ public WeightRoundRobinLoadBalanceSelector(List> clusterGroup) { this.totalWeight = totalWeight; } - @Override @SuppressWarnings("ConstantConditions") public T select() { diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/HeartbeatItem.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/HeartbeatItem.java new file mode 100644 index 0000000000..1b66c28f23 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/HeartbeatItem.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; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class HeartbeatItem { + + private String topic; + + private String url; + +} 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 index 306c0c4e2c..6f64617e27 100644 --- 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 @@ -93,5 +93,3 @@ 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 index 7683beee78..d05c7ce20e 100644 --- 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 @@ -26,7 +26,12 @@ public enum SubscriptionMode { /** * clustering */ - CLUSTERING("CLUSTERING"); + CLUSTERING("CLUSTERING"), + + /** + * UNRECOGNIZED + */ + UNRECOGNIZED("UNRECOGNIZED"); private final String mode; 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 index 996cbfe14d..c6d19eaf9e 100644 --- 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 @@ -18,6 +18,7 @@ package org.apache.eventmesh.common.protocol; public enum SubscriptionType { + /** * SYNC */ @@ -25,7 +26,12 @@ public enum SubscriptionType { /** * ASYNC */ - ASYNC("ASYNC"); + ASYNC("ASYNC"), + + /** + * UNRECOGNIZED + */ + UNRECOGNIZED("UNRECOGNIZED"); private final String type; diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/Operation.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/Operation.java index 486ecf4cec..07e2407f49 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/Operation.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/Operation.java @@ -407,7 +407,7 @@ public static Builder newBuilder(Operation prototype) { @Override public Builder toBuilder() { - return this == DEFAULT_INSTANCE + return this.equals(DEFAULT_INSTANCE) ? new Builder() : new Builder().mergeFrom(this); } @@ -545,7 +545,7 @@ public Builder mergeFrom(com.google.protobuf.Message other) { } public Builder mergeFrom(Operation other) { - if (other == Operation.getDefaultInstance()) { + if (other.equals(Operation.getDefaultInstance())) { return this; } if (!other.getChannelName().isEmpty()) { diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/QueryOperationsRequest.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/QueryOperationsRequest.java index 843b6f3ae0..27401bb4b9 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/QueryOperationsRequest.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/QueryOperationsRequest.java @@ -383,7 +383,7 @@ public static Builder newBuilder(QueryOperationsRequest prototype) { @Override public Builder toBuilder() { - return this == DEFAULT_INSTANCE + return this.equals(DEFAULT_INSTANCE) ? new Builder() : new Builder().mergeFrom(this); } @@ -518,7 +518,7 @@ public Builder mergeFrom(com.google.protobuf.Message other) { } public Builder mergeFrom(QueryOperationsRequest other) { - if (other == QueryOperationsRequest.getDefaultInstance()) { + if (other.equals(QueryOperationsRequest.getDefaultInstance())) { return this; } if (!other.getServiceName().isEmpty()) { diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/QueryOperationsResponse.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/QueryOperationsResponse.java index 03a7c8c03c..da89c60580 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/QueryOperationsResponse.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/QueryOperationsResponse.java @@ -335,7 +335,7 @@ public static Builder newBuilder(QueryOperationsResponse prototype) { @Override public Builder toBuilder() { - return this == DEFAULT_INSTANCE + return this.equals(DEFAULT_INSTANCE) ? new Builder() : new Builder().mergeFrom(this); } @@ -481,7 +481,7 @@ public Builder mergeFrom(com.google.protobuf.Message other) { } public Builder mergeFrom(QueryOperationsResponse other) { - if (other == QueryOperationsResponse.getDefaultInstance()) { + if (other.equals(QueryOperationsResponse.getDefaultInstance())) { return this; } if (operationsBuilder_ == null) { diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/RegistryRequest.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/RegistryRequest.java index b80ad2f5ea..ae65571879 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/RegistryRequest.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/RegistryRequest.java @@ -342,7 +342,7 @@ public static Builder newBuilder(RegistryRequest prototype) { @Override public Builder toBuilder() { - return this == DEFAULT_INSTANCE + return this.equals(DEFAULT_INSTANCE) ? new Builder() : new Builder().mergeFrom(this); } @@ -477,7 +477,7 @@ public Builder mergeFrom(com.google.protobuf.Message other) { } public Builder mergeFrom(RegistryRequest other) { - if (other == RegistryRequest.getDefaultInstance()) { + if (other.equals(RegistryRequest.getDefaultInstance())) { return this; } if (!other.getFileName().isEmpty()) { diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/RegistryResponse.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/RegistryResponse.java index 3aa0e1c43b..60bc018587 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/RegistryResponse.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/catalog/protos/RegistryResponse.java @@ -262,7 +262,7 @@ public static Builder newBuilder(RegistryResponse prototype) { @Override public Builder toBuilder() { - return this == DEFAULT_INSTANCE + return this.equals(DEFAULT_INSTANCE) ? new Builder() : new Builder().mergeFrom(this); } @@ -390,7 +390,7 @@ public Builder mergeFrom(com.google.protobuf.Message other) { } public Builder mergeFrom(RegistryResponse other) { - if (other == RegistryResponse.getDefaultInstance()) { + if (other.equals(RegistryResponse.getDefaultInstance())) { return this; } this.mergeUnknownFields(other.unknownFields); diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEvent.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEvent.java new file mode 100644 index 0000000000..f04108f397 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEvent.java @@ -0,0 +1,3567 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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-cloudevents.proto + +package org.apache.eventmesh.common.protocol.grpc.cloudevents; + +/** + * Protobuf type {@code org.apache.eventmesh.cloudevents.v1.CloudEvent} + */ +public final class CloudEvent extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:org.apache.eventmesh.cloudevents.v1.CloudEvent) + CloudEventOrBuilder { +private static final long serialVersionUID = 0L; + // Use CloudEvent.newBuilder() to construct. + private CloudEvent(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private CloudEvent() { + id_ = ""; + source_ = ""; + specVersion_ = ""; + type_ = ""; + } + + @Override + @SuppressWarnings({"unused"}) + protected Object newInstance( + UnusedPrivateParameter unused) { + return new CloudEvent(); + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CloudEvent( + 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; + case 10: { + String s = input.readStringRequireUtf8(); + + id_ = s; + break; + } + case 18: { + String s = input.readStringRequireUtf8(); + + source_ = s; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + + specVersion_ = s; + break; + } + case 34: { + String s = input.readStringRequireUtf8(); + + type_ = s; + break; + } + case 42: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + attributes_ = com.google.protobuf.MapField.newMapField( + AttributesDefaultEntryHolder.defaultEntry); + mutable_bitField0_ |= 0x00000001; + } + com.google.protobuf.MapEntry + attributes__ = input.readMessage( + AttributesDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); + attributes_.getMutableMap().put( + attributes__.getKey(), attributes__.getValue()); + break; + } + case 50: { + data_ = input.readBytes(); + dataCase_ = 6; + break; + } + case 58: { + String s = input.readStringRequireUtf8(); + dataCase_ = 7; + data_ = s; + break; + } + case 66: { + com.google.protobuf.Any.Builder subBuilder = null; + if (dataCase_ == 8) { + subBuilder = ((com.google.protobuf.Any) data_).toBuilder(); + } + data_ = + input.readMessage(com.google.protobuf.Any.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom((com.google.protobuf.Any) data_); + data_ = subBuilder.buildPartial(); + } + dataCase_ = 8; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().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 EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + @Override + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 5: + return internalGetAttributes(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_fieldAccessorTable + .ensureFieldAccessorsInitialized( + CloudEvent.class, Builder.class); + } + + public interface CloudEventAttributeValueOrBuilder extends + // @@protoc_insertion_point(interface_extends:org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue) + com.google.protobuf.MessageOrBuilder { + + /** + * bool ce_boolean = 1; + * @return Whether the ceBoolean field is set. + */ + boolean hasCeBoolean(); + /** + * bool ce_boolean = 1; + * @return The ceBoolean. + */ + boolean getCeBoolean(); + + /** + * int32 ce_integer = 2; + * @return Whether the ceInteger field is set. + */ + boolean hasCeInteger(); + /** + * int32 ce_integer = 2; + * @return The ceInteger. + */ + int getCeInteger(); + + /** + * string ce_string = 3; + * @return Whether the ceString field is set. + */ + boolean hasCeString(); + /** + * string ce_string = 3; + * @return The ceString. + */ + String getCeString(); + /** + * string ce_string = 3; + * @return The bytes for ceString. + */ + com.google.protobuf.ByteString + getCeStringBytes(); + + /** + * bytes ce_bytes = 4; + * @return Whether the ceBytes field is set. + */ + boolean hasCeBytes(); + /** + * bytes ce_bytes = 4; + * @return The ceBytes. + */ + com.google.protobuf.ByteString getCeBytes(); + + /** + * string ce_uri = 5; + * @return Whether the ceUri field is set. + */ + boolean hasCeUri(); + /** + * string ce_uri = 5; + * @return The ceUri. + */ + String getCeUri(); + /** + * string ce_uri = 5; + * @return The bytes for ceUri. + */ + com.google.protobuf.ByteString + getCeUriBytes(); + + /** + * string ce_uri_ref = 6; + * @return Whether the ceUriRef field is set. + */ + boolean hasCeUriRef(); + /** + * string ce_uri_ref = 6; + * @return The ceUriRef. + */ + String getCeUriRef(); + /** + * string ce_uri_ref = 6; + * @return The bytes for ceUriRef. + */ + com.google.protobuf.ByteString + getCeUriRefBytes(); + + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + * @return Whether the ceTimestamp field is set. + */ + boolean hasCeTimestamp(); + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + * @return The ceTimestamp. + */ + com.google.protobuf.Timestamp getCeTimestamp(); + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + */ + com.google.protobuf.TimestampOrBuilder getCeTimestampOrBuilder(); + + public CloudEventAttributeValue.AttrCase getAttrCase(); + } + /** + * Protobuf type {@code org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue} + */ + public static final class CloudEventAttributeValue extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue) + CloudEventAttributeValueOrBuilder { + private static final long serialVersionUID = 0L; + // Use CloudEventAttributeValue.newBuilder() to construct. + private CloudEventAttributeValue(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private CloudEventAttributeValue() { + } + + @Override + @SuppressWarnings({"unused"}) + protected Object newInstance( + UnusedPrivateParameter unused) { + return new CloudEventAttributeValue(); + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CloudEventAttributeValue( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new NullPointerException(); + } + 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; + case 8: { + attr_ = input.readBool(); + attrCase_ = 1; + break; + } + case 16: { + attr_ = input.readInt32(); + attrCase_ = 2; + break; + } + case 26: { + String s = input.readStringRequireUtf8(); + attrCase_ = 3; + attr_ = s; + break; + } + case 34: { + attr_ = input.readBytes(); + attrCase_ = 4; + break; + } + case 42: { + String s = input.readStringRequireUtf8(); + attrCase_ = 5; + attr_ = s; + break; + } + case 50: { + String s = input.readStringRequireUtf8(); + attrCase_ = 6; + attr_ = s; + break; + } + case 58: { + com.google.protobuf.Timestamp.Builder subBuilder = null; + if (attrCase_ == 7) { + subBuilder = ((com.google.protobuf.Timestamp) attr_).toBuilder(); + } + attr_ = + input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom((com.google.protobuf.Timestamp) attr_); + attr_ = subBuilder.buildPartial(); + } + attrCase_ = 7; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().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 EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_descriptor; + } + + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_fieldAccessorTable + .ensureFieldAccessorsInitialized( + CloudEventAttributeValue.class, Builder.class); + } + + private int attrCase_ = 0; + private Object attr_; + public enum AttrCase + implements com.google.protobuf.Internal.EnumLite, + InternalOneOfEnum { + CE_BOOLEAN(1), + CE_INTEGER(2), + CE_STRING(3), + CE_BYTES(4), + CE_URI(5), + CE_URI_REF(6), + CE_TIMESTAMP(7), + ATTR_NOT_SET(0); + private final int value; + private AttrCase(int value) { + this.value = value; + } + /** + * @param value The number of the enum to look for. + * @return The enum associated with the given number. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @Deprecated + public static AttrCase valueOf(int value) { + return forNumber(value); + } + + public static AttrCase forNumber(int value) { + switch (value) { + case 1: return CE_BOOLEAN; + case 2: return CE_INTEGER; + case 3: return CE_STRING; + case 4: return CE_BYTES; + case 5: return CE_URI; + case 6: return CE_URI_REF; + case 7: return CE_TIMESTAMP; + case 0: return ATTR_NOT_SET; + default: return null; + } + } + public int getNumber() { + return this.value; + } + }; + + public AttrCase + getAttrCase() { + return AttrCase.forNumber( + attrCase_); + } + + public static final int CE_BOOLEAN_FIELD_NUMBER = 1; + /** + * bool ce_boolean = 1; + * @return Whether the ceBoolean field is set. + */ + @Override + public boolean hasCeBoolean() { + return attrCase_ == 1; + } + /** + * bool ce_boolean = 1; + * @return The ceBoolean. + */ + @Override + public boolean getCeBoolean() { + if (attrCase_ == 1) { + return (Boolean) attr_; + } + return false; + } + + public static final int CE_INTEGER_FIELD_NUMBER = 2; + /** + * int32 ce_integer = 2; + * @return Whether the ceInteger field is set. + */ + @Override + public boolean hasCeInteger() { + return attrCase_ == 2; + } + /** + * int32 ce_integer = 2; + * @return The ceInteger. + */ + @Override + public int getCeInteger() { + if (attrCase_ == 2) { + return (Integer) attr_; + } + return 0; + } + + public static final int CE_STRING_FIELD_NUMBER = 3; + /** + * string ce_string = 3; + * @return Whether the ceString field is set. + */ + public boolean hasCeString() { + return attrCase_ == 3; + } + /** + * string ce_string = 3; + * @return The ceString. + */ + public String getCeString() { + Object ref = ""; + if (attrCase_ == 3) { + ref = attr_; + } + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (attrCase_ == 3) { + attr_ = s; + } + return s; + } + } + /** + * string ce_string = 3; + * @return The bytes for ceString. + */ + public com.google.protobuf.ByteString + getCeStringBytes() { + Object ref = ""; + if (attrCase_ == 3) { + ref = attr_; + } + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + if (attrCase_ == 3) { + attr_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CE_BYTES_FIELD_NUMBER = 4; + /** + * bytes ce_bytes = 4; + * @return Whether the ceBytes field is set. + */ + @Override + public boolean hasCeBytes() { + return attrCase_ == 4; + } + /** + * bytes ce_bytes = 4; + * @return The ceBytes. + */ + @Override + public com.google.protobuf.ByteString getCeBytes() { + if (attrCase_ == 4) { + return (com.google.protobuf.ByteString) attr_; + } + return com.google.protobuf.ByteString.EMPTY; + } + + public static final int CE_URI_FIELD_NUMBER = 5; + /** + * string ce_uri = 5; + * @return Whether the ceUri field is set. + */ + public boolean hasCeUri() { + return attrCase_ == 5; + } + /** + * string ce_uri = 5; + * @return The ceUri. + */ + public String getCeUri() { + Object ref = ""; + if (attrCase_ == 5) { + ref = attr_; + } + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (attrCase_ == 5) { + attr_ = s; + } + return s; + } + } + /** + * string ce_uri = 5; + * @return The bytes for ceUri. + */ + public com.google.protobuf.ByteString + getCeUriBytes() { + Object ref = ""; + if (attrCase_ == 5) { + ref = attr_; + } + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + if (attrCase_ == 5) { + attr_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CE_URI_REF_FIELD_NUMBER = 6; + /** + * string ce_uri_ref = 6; + * @return Whether the ceUriRef field is set. + */ + public boolean hasCeUriRef() { + return attrCase_ == 6; + } + /** + * string ce_uri_ref = 6; + * @return The ceUriRef. + */ + public String getCeUriRef() { + Object ref = ""; + if (attrCase_ == 6) { + ref = attr_; + } + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (attrCase_ == 6) { + attr_ = s; + } + return s; + } + } + /** + * string ce_uri_ref = 6; + * @return The bytes for ceUriRef. + */ + public com.google.protobuf.ByteString + getCeUriRefBytes() { + Object ref = ""; + if (attrCase_ == 6) { + ref = attr_; + } + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + if (attrCase_ == 6) { + attr_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CE_TIMESTAMP_FIELD_NUMBER = 7; + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + * @return Whether the ceTimestamp field is set. + */ + @Override + public boolean hasCeTimestamp() { + return attrCase_ == 7; + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + * @return The ceTimestamp. + */ + @Override + public com.google.protobuf.Timestamp getCeTimestamp() { + if (attrCase_ == 7) { + return (com.google.protobuf.Timestamp) attr_; + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + */ + @Override + public com.google.protobuf.TimestampOrBuilder getCeTimestampOrBuilder() { + if (attrCase_ == 7) { + return (com.google.protobuf.Timestamp) attr_; + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } + + private byte memoizedIsInitialized = -1; + @Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (attrCase_ == 1) { + output.writeBool( + 1, (boolean)((Boolean) attr_)); + } + if (attrCase_ == 2) { + output.writeInt32( + 2, (int)((Integer) attr_)); + } + if (attrCase_ == 3) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, attr_); + } + if (attrCase_ == 4) { + output.writeBytes( + 4, (com.google.protobuf.ByteString) attr_); + } + if (attrCase_ == 5) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, attr_); + } + if (attrCase_ == 6) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 6, attr_); + } + if (attrCase_ == 7) { + output.writeMessage(7, (com.google.protobuf.Timestamp) attr_); + } + unknownFields.writeTo(output); + } + + @Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (attrCase_ == 1) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize( + 1, (boolean)((Boolean) attr_)); + } + if (attrCase_ == 2) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size( + 2, (int)((Integer) attr_)); + } + if (attrCase_ == 3) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, attr_); + } + if (attrCase_ == 4) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize( + 4, (com.google.protobuf.ByteString) attr_); + } + if (attrCase_ == 5) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, attr_); + } + if (attrCase_ == 6) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, attr_); + } + if (attrCase_ == 7) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(7, (com.google.protobuf.Timestamp) attr_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof CloudEventAttributeValue)) { + return super.equals(obj); + } + CloudEventAttributeValue other = (CloudEventAttributeValue) obj; + + if (!getAttrCase().equals(other.getAttrCase())) return false; + switch (attrCase_) { + case 1: + if (getCeBoolean() + != other.getCeBoolean()) return false; + break; + case 2: + if (getCeInteger() + != other.getCeInteger()) return false; + break; + case 3: + if (!getCeString() + .equals(other.getCeString())) return false; + break; + case 4: + if (!getCeBytes() + .equals(other.getCeBytes())) return false; + break; + case 5: + if (!getCeUri() + .equals(other.getCeUri())) return false; + break; + case 6: + if (!getCeUriRef() + .equals(other.getCeUriRef())) return false; + break; + case 7: + if (!getCeTimestamp() + .equals(other.getCeTimestamp())) return false; + break; + case 0: + default: + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + switch (attrCase_) { + case 1: + hash = (37 * hash) + CE_BOOLEAN_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getCeBoolean()); + break; + case 2: + hash = (37 * hash) + CE_INTEGER_FIELD_NUMBER; + hash = (53 * hash) + getCeInteger(); + break; + case 3: + hash = (37 * hash) + CE_STRING_FIELD_NUMBER; + hash = (53 * hash) + getCeString().hashCode(); + break; + case 4: + hash = (37 * hash) + CE_BYTES_FIELD_NUMBER; + hash = (53 * hash) + getCeBytes().hashCode(); + break; + case 5: + hash = (37 * hash) + CE_URI_FIELD_NUMBER; + hash = (53 * hash) + getCeUri().hashCode(); + break; + case 6: + hash = (37 * hash) + CE_URI_REF_FIELD_NUMBER; + hash = (53 * hash) + getCeUriRef().hashCode(); + break; + case 7: + hash = (37 * hash) + CE_TIMESTAMP_FIELD_NUMBER; + hash = (53 * hash) + getCeTimestamp().hashCode(); + break; + case 0: + default: + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static CloudEventAttributeValue parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static CloudEventAttributeValue parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static CloudEventAttributeValue parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static CloudEventAttributeValue parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static CloudEventAttributeValue parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static CloudEventAttributeValue parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static CloudEventAttributeValue parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static CloudEventAttributeValue 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 CloudEventAttributeValue parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static CloudEventAttributeValue 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 CloudEventAttributeValue parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static CloudEventAttributeValue parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(CloudEventAttributeValue prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @Override + 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 org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue) + CloudEventAttributeValueOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_descriptor; + } + + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_fieldAccessorTable + .ensureFieldAccessorsInitialized( + CloudEventAttributeValue.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @Override + public Builder clear() { + super.clear(); + attrCase_ = 0; + attr_ = null; + return this; + } + + @Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_descriptor; + } + + @Override + public CloudEventAttributeValue getDefaultInstanceForType() { + return CloudEventAttributeValue.getDefaultInstance(); + } + + @Override + public CloudEventAttributeValue build() { + CloudEventAttributeValue result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @Override + public CloudEventAttributeValue buildPartial() { + CloudEventAttributeValue result = new CloudEventAttributeValue(this); + if (attrCase_ == 1) { + result.attr_ = attr_; + } + if (attrCase_ == 2) { + result.attr_ = attr_; + } + if (attrCase_ == 3) { + result.attr_ = attr_; + } + if (attrCase_ == 4) { + result.attr_ = attr_; + } + if (attrCase_ == 5) { + result.attr_ = attr_; + } + if (attrCase_ == 6) { + result.attr_ = attr_; + } + if (attrCase_ == 7) { + if (ceTimestampBuilder_ == null) { + result.attr_ = attr_; + } else { + result.attr_ = ceTimestampBuilder_.build(); + } + } + result.attrCase_ = attrCase_; + onBuilt(); + return result; + } + + @Override + public Builder clone() { + return super.clone(); + } + @Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return super.setField(field, value); + } + @Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return super.setRepeatedField(field, index, value); + } + @Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return super.addRepeatedField(field, value); + } + @Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof CloudEventAttributeValue) { + return mergeFrom((CloudEventAttributeValue)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(CloudEventAttributeValue other) { + if (other == CloudEventAttributeValue.getDefaultInstance()) return this; + switch (other.getAttrCase()) { + case CE_BOOLEAN: { + setCeBoolean(other.getCeBoolean()); + break; + } + case CE_INTEGER: { + setCeInteger(other.getCeInteger()); + break; + } + case CE_STRING: { + attrCase_ = 3; + attr_ = other.attr_; + onChanged(); + break; + } + case CE_BYTES: { + setCeBytes(other.getCeBytes()); + break; + } + case CE_URI: { + attrCase_ = 5; + attr_ = other.attr_; + onChanged(); + break; + } + case CE_URI_REF: { + attrCase_ = 6; + attr_ = other.attr_; + onChanged(); + break; + } + case CE_TIMESTAMP: { + mergeCeTimestamp(other.getCeTimestamp()); + break; + } + case ATTR_NOT_SET: { + break; + } + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @Override + public final boolean isInitialized() { + return true; + } + + @Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + CloudEventAttributeValue parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (CloudEventAttributeValue) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int attrCase_ = 0; + private Object attr_; + public AttrCase + getAttrCase() { + return AttrCase.forNumber( + attrCase_); + } + + public Builder clearAttr() { + attrCase_ = 0; + attr_ = null; + onChanged(); + return this; + } + + + /** + * bool ce_boolean = 1; + * @return Whether the ceBoolean field is set. + */ + public boolean hasCeBoolean() { + return attrCase_ == 1; + } + /** + * bool ce_boolean = 1; + * @return The ceBoolean. + */ + public boolean getCeBoolean() { + if (attrCase_ == 1) { + return (Boolean) attr_; + } + return false; + } + /** + * bool ce_boolean = 1; + * @param value The ceBoolean to set. + * @return This builder for chaining. + */ + public Builder setCeBoolean(boolean value) { + attrCase_ = 1; + attr_ = value; + onChanged(); + return this; + } + /** + * bool ce_boolean = 1; + * @return This builder for chaining. + */ + public Builder clearCeBoolean() { + if (attrCase_ == 1) { + attrCase_ = 0; + attr_ = null; + onChanged(); + } + return this; + } + + /** + * int32 ce_integer = 2; + * @return Whether the ceInteger field is set. + */ + public boolean hasCeInteger() { + return attrCase_ == 2; + } + /** + * int32 ce_integer = 2; + * @return The ceInteger. + */ + public int getCeInteger() { + if (attrCase_ == 2) { + return (Integer) attr_; + } + return 0; + } + /** + * int32 ce_integer = 2; + * @param value The ceInteger to set. + * @return This builder for chaining. + */ + public Builder setCeInteger(int value) { + attrCase_ = 2; + attr_ = value; + onChanged(); + return this; + } + /** + * int32 ce_integer = 2; + * @return This builder for chaining. + */ + public Builder clearCeInteger() { + if (attrCase_ == 2) { + attrCase_ = 0; + attr_ = null; + onChanged(); + } + return this; + } + + /** + * string ce_string = 3; + * @return Whether the ceString field is set. + */ + @Override + public boolean hasCeString() { + return attrCase_ == 3; + } + /** + * string ce_string = 3; + * @return The ceString. + */ + @Override + public String getCeString() { + Object ref = ""; + if (attrCase_ == 3) { + ref = attr_; + } + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (attrCase_ == 3) { + attr_ = s; + } + return s; + } else { + return (String) ref; + } + } + /** + * string ce_string = 3; + * @return The bytes for ceString. + */ + @Override + public com.google.protobuf.ByteString + getCeStringBytes() { + Object ref = ""; + if (attrCase_ == 3) { + ref = attr_; + } + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + if (attrCase_ == 3) { + attr_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string ce_string = 3; + * @param value The ceString to set. + * @return This builder for chaining. + */ + public Builder setCeString( + String value) { + if (value == null) { + throw new NullPointerException(); + } + attrCase_ = 3; + attr_ = value; + onChanged(); + return this; + } + /** + * string ce_string = 3; + * @return This builder for chaining. + */ + public Builder clearCeString() { + if (attrCase_ == 3) { + attrCase_ = 0; + attr_ = null; + onChanged(); + } + return this; + } + /** + * string ce_string = 3; + * @param value The bytes for ceString to set. + * @return This builder for chaining. + */ + public Builder setCeStringBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + attrCase_ = 3; + attr_ = value; + onChanged(); + return this; + } + + /** + * bytes ce_bytes = 4; + * @return Whether the ceBytes field is set. + */ + public boolean hasCeBytes() { + return attrCase_ == 4; + } + /** + * bytes ce_bytes = 4; + * @return The ceBytes. + */ + public com.google.protobuf.ByteString getCeBytes() { + if (attrCase_ == 4) { + return (com.google.protobuf.ByteString) attr_; + } + return com.google.protobuf.ByteString.EMPTY; + } + /** + * bytes ce_bytes = 4; + * @param value The ceBytes to set. + * @return This builder for chaining. + */ + public Builder setCeBytes(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + attrCase_ = 4; + attr_ = value; + onChanged(); + return this; + } + /** + * bytes ce_bytes = 4; + * @return This builder for chaining. + */ + public Builder clearCeBytes() { + if (attrCase_ == 4) { + attrCase_ = 0; + attr_ = null; + onChanged(); + } + return this; + } + + /** + * string ce_uri = 5; + * @return Whether the ceUri field is set. + */ + @Override + public boolean hasCeUri() { + return attrCase_ == 5; + } + /** + * string ce_uri = 5; + * @return The ceUri. + */ + @Override + public String getCeUri() { + Object ref = ""; + if (attrCase_ == 5) { + ref = attr_; + } + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (attrCase_ == 5) { + attr_ = s; + } + return s; + } else { + return (String) ref; + } + } + /** + * string ce_uri = 5; + * @return The bytes for ceUri. + */ + @Override + public com.google.protobuf.ByteString + getCeUriBytes() { + Object ref = ""; + if (attrCase_ == 5) { + ref = attr_; + } + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + if (attrCase_ == 5) { + attr_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string ce_uri = 5; + * @param value The ceUri to set. + * @return This builder for chaining. + */ + public Builder setCeUri( + String value) { + if (value == null) { + throw new NullPointerException(); + } + attrCase_ = 5; + attr_ = value; + onChanged(); + return this; + } + /** + * string ce_uri = 5; + * @return This builder for chaining. + */ + public Builder clearCeUri() { + if (attrCase_ == 5) { + attrCase_ = 0; + attr_ = null; + onChanged(); + } + return this; + } + /** + * string ce_uri = 5; + * @param value The bytes for ceUri to set. + * @return This builder for chaining. + */ + public Builder setCeUriBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + attrCase_ = 5; + attr_ = value; + onChanged(); + return this; + } + + /** + * string ce_uri_ref = 6; + * @return Whether the ceUriRef field is set. + */ + @Override + public boolean hasCeUriRef() { + return attrCase_ == 6; + } + /** + * string ce_uri_ref = 6; + * @return The ceUriRef. + */ + @Override + public String getCeUriRef() { + Object ref = ""; + if (attrCase_ == 6) { + ref = attr_; + } + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (attrCase_ == 6) { + attr_ = s; + } + return s; + } else { + return (String) ref; + } + } + /** + * string ce_uri_ref = 6; + * @return The bytes for ceUriRef. + */ + @Override + public com.google.protobuf.ByteString + getCeUriRefBytes() { + Object ref = ""; + if (attrCase_ == 6) { + ref = attr_; + } + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + if (attrCase_ == 6) { + attr_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string ce_uri_ref = 6; + * @param value The ceUriRef to set. + * @return This builder for chaining. + */ + public Builder setCeUriRef( + String value) { + if (value == null) { + throw new NullPointerException(); + } + attrCase_ = 6; + attr_ = value; + onChanged(); + return this; + } + /** + * string ce_uri_ref = 6; + * @return This builder for chaining. + */ + public Builder clearCeUriRef() { + if (attrCase_ == 6) { + attrCase_ = 0; + attr_ = null; + onChanged(); + } + return this; + } + /** + * string ce_uri_ref = 6; + * @param value The bytes for ceUriRef to set. + * @return This builder for chaining. + */ + public Builder setCeUriRefBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + attrCase_ = 6; + attr_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> ceTimestampBuilder_; + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + * @return Whether the ceTimestamp field is set. + */ + @Override + public boolean hasCeTimestamp() { + return attrCase_ == 7; + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + * @return The ceTimestamp. + */ + @Override + public com.google.protobuf.Timestamp getCeTimestamp() { + if (ceTimestampBuilder_ == null) { + if (attrCase_ == 7) { + return (com.google.protobuf.Timestamp) attr_; + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } else { + if (attrCase_ == 7) { + return ceTimestampBuilder_.getMessage(); + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + */ + public Builder setCeTimestamp(com.google.protobuf.Timestamp value) { + if (ceTimestampBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + attr_ = value; + onChanged(); + } else { + ceTimestampBuilder_.setMessage(value); + } + attrCase_ = 7; + return this; + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + */ + public Builder setCeTimestamp( + com.google.protobuf.Timestamp.Builder builderForValue) { + if (ceTimestampBuilder_ == null) { + attr_ = builderForValue.build(); + onChanged(); + } else { + ceTimestampBuilder_.setMessage(builderForValue.build()); + } + attrCase_ = 7; + return this; + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + */ + public Builder mergeCeTimestamp(com.google.protobuf.Timestamp value) { + if (ceTimestampBuilder_ == null) { + if (attrCase_ == 7 && + attr_ != com.google.protobuf.Timestamp.getDefaultInstance()) { + attr_ = com.google.protobuf.Timestamp.newBuilder((com.google.protobuf.Timestamp) attr_) + .mergeFrom(value).buildPartial(); + } else { + attr_ = value; + } + onChanged(); + } else { + if (attrCase_ == 7) { + ceTimestampBuilder_.mergeFrom(value); + } else { + ceTimestampBuilder_.setMessage(value); + } + } + attrCase_ = 7; + return this; + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + */ + public Builder clearCeTimestamp() { + if (ceTimestampBuilder_ == null) { + if (attrCase_ == 7) { + attrCase_ = 0; + attr_ = null; + onChanged(); + } + } else { + if (attrCase_ == 7) { + attrCase_ = 0; + attr_ = null; + } + ceTimestampBuilder_.clear(); + } + return this; + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + */ + public com.google.protobuf.Timestamp.Builder getCeTimestampBuilder() { + return getCeTimestampFieldBuilder().getBuilder(); + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + */ + @Override + public com.google.protobuf.TimestampOrBuilder getCeTimestampOrBuilder() { + if ((attrCase_ == 7) && (ceTimestampBuilder_ != null)) { + return ceTimestampBuilder_.getMessageOrBuilder(); + } else { + if (attrCase_ == 7) { + return (com.google.protobuf.Timestamp) attr_; + } + return com.google.protobuf.Timestamp.getDefaultInstance(); + } + } + /** + * .google.protobuf.Timestamp ce_timestamp = 7; + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> + getCeTimestampFieldBuilder() { + if (ceTimestampBuilder_ == null) { + if (!(attrCase_ == 7)) { + attr_ = com.google.protobuf.Timestamp.getDefaultInstance(); + } + ceTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>( + (com.google.protobuf.Timestamp) attr_, + getParentForChildren(), + isClean()); + attr_ = null; + } + attrCase_ = 7; + onChanged();; + return ceTimestampBuilder_; + } + @Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue) + } + + // @@protoc_insertion_point(class_scope:org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue) + private static final CloudEventAttributeValue DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new CloudEventAttributeValue(); + } + + public static CloudEventAttributeValue getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @Override + public CloudEventAttributeValue parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CloudEventAttributeValue(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @Override + public CloudEventAttributeValue getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private int dataCase_ = 0; + private Object data_; + public enum DataCase + implements com.google.protobuf.Internal.EnumLite, + InternalOneOfEnum { + BINARY_DATA(6), + TEXT_DATA(7), + PROTO_DATA(8), + DATA_NOT_SET(0); + private final int value; + private DataCase(int value) { + this.value = value; + } + /** + * @param value The number of the enum to look for. + * @return The enum associated with the given number. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @Deprecated + public static DataCase valueOf(int value) { + return forNumber(value); + } + + public static DataCase forNumber(int value) { + switch (value) { + case 6: return BINARY_DATA; + case 7: return TEXT_DATA; + case 8: return PROTO_DATA; + case 0: return DATA_NOT_SET; + default: return null; + } + } + public int getNumber() { + return this.value; + } + }; + + public DataCase + getDataCase() { + return DataCase.forNumber( + dataCase_); + } + + public static final int ID_FIELD_NUMBER = 1; + private volatile Object id_; + /** + *
+   * Required Attributes
+   * 
+ * + * string id = 1; + * @return The id. + */ + @Override + public String getId() { + Object ref = id_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + id_ = s; + return s; + } + } + /** + *
+   * Required Attributes
+   * 
+ * + * string id = 1; + * @return The bytes for id. + */ + @Override + public com.google.protobuf.ByteString + getIdBytes() { + Object ref = id_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SOURCE_FIELD_NUMBER = 2; + private volatile Object source_; + /** + *
+   * URI-reference
+   * 
+ * + * string source = 2; + * @return The source. + */ + @Override + public String getSource() { + Object ref = source_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + source_ = s; + return s; + } + } + /** + *
+   * URI-reference
+   * 
+ * + * string source = 2; + * @return The bytes for source. + */ + @Override + public com.google.protobuf.ByteString + getSourceBytes() { + Object ref = source_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + source_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SPEC_VERSION_FIELD_NUMBER = 3; + private volatile Object specVersion_; + /** + * string spec_version = 3; + * @return The specVersion. + */ + @Override + public String getSpecVersion() { + Object ref = specVersion_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + specVersion_ = s; + return s; + } + } + /** + * string spec_version = 3; + * @return The bytes for specVersion. + */ + @Override + public com.google.protobuf.ByteString + getSpecVersionBytes() { + Object ref = specVersion_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + specVersion_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TYPE_FIELD_NUMBER = 4; + private volatile Object type_; + /** + * string type = 4; + * @return The type. + */ + @Override + public String getType() { + Object ref = type_; + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + type_ = s; + return s; + } + } + /** + * string type = 4; + * @return The bytes for type. + */ + @Override + public com.google.protobuf.ByteString + getTypeBytes() { + Object ref = type_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + type_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int ATTRIBUTES_FIELD_NUMBER = 5; + private static final class AttributesDefaultEntryHolder { + static final com.google.protobuf.MapEntry< + String, CloudEventAttributeValue> defaultEntry = + com.google.protobuf.MapEntry + .newDefaultInstance( + EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_AttributesEntry_descriptor, + com.google.protobuf.WireFormat.FieldType.STRING, + "", + com.google.protobuf.WireFormat.FieldType.MESSAGE, + CloudEventAttributeValue.getDefaultInstance()); + } + private com.google.protobuf.MapField< + String, CloudEventAttributeValue> attributes_; + private com.google.protobuf.MapField + internalGetAttributes() { + if (attributes_ == null) { + return com.google.protobuf.MapField.emptyMapField( + AttributesDefaultEntryHolder.defaultEntry); + } + return attributes_; + } + + public int getAttributesCount() { + return internalGetAttributes().getMap().size(); + } + /** + *
+   * Optional & Extension Attributes
+   * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + + @Override + public boolean containsAttributes( + String key) { + if (key == null) { throw new NullPointerException("map key"); } + return internalGetAttributes().getMap().containsKey(key); + } + /** + * Use {@link #getAttributesMap()} instead. + */ + @Override + @Deprecated + public java.util.Map getAttributes() { + return getAttributesMap(); + } + /** + *
+   * Optional & Extension Attributes
+   * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + @Override + + public java.util.Map getAttributesMap() { + return internalGetAttributes().getMap(); + } + /** + *
+   * Optional & Extension Attributes
+   * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + @Override + + public CloudEventAttributeValue getAttributesOrDefault( + String key, + CloudEventAttributeValue defaultValue) { + if (key == null) { throw new NullPointerException("map key"); } + java.util.Map map = + internalGetAttributes().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + *
+   * Optional & Extension Attributes
+   * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + @Override + + public CloudEventAttributeValue getAttributesOrThrow( + String key) { + if (key == null) { throw new NullPointerException("map key"); } + java.util.Map map = + internalGetAttributes().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + public static final int BINARY_DATA_FIELD_NUMBER = 6; + /** + * bytes binary_data = 6; + * @return Whether the binaryData field is set. + */ + @Override + public boolean hasBinaryData() { + return dataCase_ == 6; + } + /** + * bytes binary_data = 6; + * @return The binaryData. + */ + @Override + public com.google.protobuf.ByteString getBinaryData() { + if (dataCase_ == 6) { + return (com.google.protobuf.ByteString) data_; + } + return com.google.protobuf.ByteString.EMPTY; + } + + public static final int TEXT_DATA_FIELD_NUMBER = 7; + /** + * string text_data = 7; + * @return Whether the textData field is set. + */ + public boolean hasTextData() { + return dataCase_ == 7; + } + /** + * string text_data = 7; + * @return The textData. + */ + public String getTextData() { + Object ref = ""; + if (dataCase_ == 7) { + ref = data_; + } + if (ref instanceof String) { + return (String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (dataCase_ == 7) { + data_ = s; + } + return s; + } + } + /** + * string text_data = 7; + * @return The bytes for textData. + */ + public com.google.protobuf.ByteString + getTextDataBytes() { + Object ref = ""; + if (dataCase_ == 7) { + ref = data_; + } + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + if (dataCase_ == 7) { + data_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PROTO_DATA_FIELD_NUMBER = 8; + /** + * .google.protobuf.Any proto_data = 8; + * @return Whether the protoData field is set. + */ + @Override + public boolean hasProtoData() { + return dataCase_ == 8; + } + /** + * .google.protobuf.Any proto_data = 8; + * @return The protoData. + */ + @Override + public com.google.protobuf.Any getProtoData() { + if (dataCase_ == 8) { + return (com.google.protobuf.Any) data_; + } + return com.google.protobuf.Any.getDefaultInstance(); + } + /** + * .google.protobuf.Any proto_data = 8; + */ + @Override + public com.google.protobuf.AnyOrBuilder getProtoDataOrBuilder() { + if (dataCase_ == 8) { + return (com.google.protobuf.Any) data_; + } + return com.google.protobuf.Any.getDefaultInstance(); + } + + private byte memoizedIsInitialized = -1; + @Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(source_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, source_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(specVersion_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, specVersion_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(type_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, type_); + } + com.google.protobuf.GeneratedMessageV3 + .serializeStringMapTo( + output, + internalGetAttributes(), + AttributesDefaultEntryHolder.defaultEntry, + 5); + if (dataCase_ == 6) { + output.writeBytes( + 6, (com.google.protobuf.ByteString) data_); + } + if (dataCase_ == 7) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 7, data_); + } + if (dataCase_ == 8) { + output.writeMessage(8, (com.google.protobuf.Any) data_); + } + unknownFields.writeTo(output); + } + + @Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(id_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(source_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, source_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(specVersion_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, specVersion_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(type_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, type_); + } + for (java.util.Map.Entry entry + : internalGetAttributes().getMap().entrySet()) { + com.google.protobuf.MapEntry + attributes__ = AttributesDefaultEntryHolder.defaultEntry.newBuilderForType() + .setKey(entry.getKey()) + .setValue(entry.getValue()) + .build(); + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, attributes__); + } + if (dataCase_ == 6) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize( + 6, (com.google.protobuf.ByteString) data_); + } + if (dataCase_ == 7) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, data_); + } + if (dataCase_ == 8) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(8, (com.google.protobuf.Any) data_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof CloudEvent)) { + return super.equals(obj); + } + CloudEvent other = (CloudEvent) obj; + + if (!getId() + .equals(other.getId())) return false; + if (!getSource() + .equals(other.getSource())) return false; + if (!getSpecVersion() + .equals(other.getSpecVersion())) return false; + if (!getType() + .equals(other.getType())) return false; + if (!internalGetAttributes().equals( + other.internalGetAttributes())) return false; + if (!getDataCase().equals(other.getDataCase())) return false; + switch (dataCase_) { + case 6: + if (!getBinaryData() + .equals(other.getBinaryData())) return false; + break; + case 7: + if (!getTextData() + .equals(other.getTextData())) return false; + break; + case 8: + if (!getProtoData() + .equals(other.getProtoData())) return false; + break; + case 0: + default: + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ID_FIELD_NUMBER; + hash = (53 * hash) + getId().hashCode(); + hash = (37 * hash) + SOURCE_FIELD_NUMBER; + hash = (53 * hash) + getSource().hashCode(); + hash = (37 * hash) + SPEC_VERSION_FIELD_NUMBER; + hash = (53 * hash) + getSpecVersion().hashCode(); + hash = (37 * hash) + TYPE_FIELD_NUMBER; + hash = (53 * hash) + getType().hashCode(); + if (!internalGetAttributes().getMap().isEmpty()) { + hash = (37 * hash) + ATTRIBUTES_FIELD_NUMBER; + hash = (53 * hash) + internalGetAttributes().hashCode(); + } + switch (dataCase_) { + case 6: + hash = (37 * hash) + BINARY_DATA_FIELD_NUMBER; + hash = (53 * hash) + getBinaryData().hashCode(); + break; + case 7: + hash = (37 * hash) + TEXT_DATA_FIELD_NUMBER; + hash = (53 * hash) + getTextData().hashCode(); + break; + case 8: + hash = (37 * hash) + PROTO_DATA_FIELD_NUMBER; + hash = (53 * hash) + getProtoData().hashCode(); + break; + case 0: + default: + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static CloudEvent parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static CloudEvent parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static CloudEvent parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static CloudEvent parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static CloudEvent parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static CloudEvent parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static CloudEvent parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static CloudEvent 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 CloudEvent parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static CloudEvent 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 CloudEvent parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static CloudEvent parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(CloudEvent prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @Override + 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 org.apache.eventmesh.cloudevents.v1.CloudEvent} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:org.apache.eventmesh.cloudevents.v1.CloudEvent) + CloudEventOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_descriptor; + } + + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMapField( + int number) { + switch (number) { + case 5: + return internalGetAttributes(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @SuppressWarnings({"rawtypes"}) + protected com.google.protobuf.MapField internalGetMutableMapField( + int number) { + switch (number) { + case 5: + return internalGetMutableAttributes(); + default: + throw new RuntimeException( + "Invalid map field number: " + number); + } + } + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_fieldAccessorTable + .ensureFieldAccessorsInitialized( + CloudEvent.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @Override + public Builder clear() { + super.clear(); + id_ = ""; + + source_ = ""; + + specVersion_ = ""; + + type_ = ""; + + internalGetMutableAttributes().clear(); + dataCase_ = 0; + data_ = null; + return this; + } + + @Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_descriptor; + } + + @Override + public CloudEvent getDefaultInstanceForType() { + return CloudEvent.getDefaultInstance(); + } + + @Override + public CloudEvent build() { + CloudEvent result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @Override + public CloudEvent buildPartial() { + CloudEvent result = new CloudEvent(this); + int from_bitField0_ = bitField0_; + result.id_ = id_; + result.source_ = source_; + result.specVersion_ = specVersion_; + result.type_ = type_; + result.attributes_ = internalGetAttributes(); + result.attributes_.makeImmutable(); + if (dataCase_ == 6) { + result.data_ = data_; + } + if (dataCase_ == 7) { + result.data_ = data_; + } + if (dataCase_ == 8) { + if (protoDataBuilder_ == null) { + result.data_ = data_; + } else { + result.data_ = protoDataBuilder_.build(); + } + } + result.dataCase_ = dataCase_; + onBuilt(); + return result; + } + + @Override + public Builder clone() { + return super.clone(); + } + @Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return super.setField(field, value); + } + @Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return super.setRepeatedField(field, index, value); + } + @Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return super.addRepeatedField(field, value); + } + @Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof CloudEvent) { + return mergeFrom((CloudEvent)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(CloudEvent other) { + if (other == CloudEvent.getDefaultInstance()) return this; + if (!other.getId().isEmpty()) { + id_ = other.id_; + onChanged(); + } + if (!other.getSource().isEmpty()) { + source_ = other.source_; + onChanged(); + } + if (!other.getSpecVersion().isEmpty()) { + specVersion_ = other.specVersion_; + onChanged(); + } + if (!other.getType().isEmpty()) { + type_ = other.type_; + onChanged(); + } + internalGetMutableAttributes().mergeFrom( + other.internalGetAttributes()); + switch (other.getDataCase()) { + case BINARY_DATA: { + setBinaryData(other.getBinaryData()); + break; + } + case TEXT_DATA: { + dataCase_ = 7; + data_ = other.data_; + onChanged(); + break; + } + case PROTO_DATA: { + mergeProtoData(other.getProtoData()); + break; + } + case DATA_NOT_SET: { + break; + } + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @Override + public final boolean isInitialized() { + return true; + } + + @Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + CloudEvent parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (CloudEvent) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int dataCase_ = 0; + private Object data_; + public DataCase + getDataCase() { + return DataCase.forNumber( + dataCase_); + } + + public Builder clearData() { + dataCase_ = 0; + data_ = null; + onChanged(); + return this; + } + + private int bitField0_; + + private Object id_ = ""; + /** + *
+     * Required Attributes
+     * 
+ * + * string id = 1; + * @return The id. + */ + public String getId() { + Object ref = id_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + id_ = s; + return s; + } else { + return (String) ref; + } + } + /** + *
+     * Required Attributes
+     * 
+ * + * string id = 1; + * @return The bytes for id. + */ + public com.google.protobuf.ByteString + getIdBytes() { + Object ref = id_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + id_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+     * Required Attributes
+     * 
+ * + * string id = 1; + * @param value The id to set. + * @return This builder for chaining. + */ + public Builder setId( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + id_ = value; + onChanged(); + return this; + } + /** + *
+     * Required Attributes
+     * 
+ * + * string id = 1; + * @return This builder for chaining. + */ + public Builder clearId() { + + id_ = getDefaultInstance().getId(); + onChanged(); + return this; + } + /** + *
+     * Required Attributes
+     * 
+ * + * string id = 1; + * @param value The bytes for id to set. + * @return This builder for chaining. + */ + public Builder setIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + id_ = value; + onChanged(); + return this; + } + + private Object source_ = ""; + /** + *
+     * URI-reference
+     * 
+ * + * string source = 2; + * @return The source. + */ + public String getSource() { + Object ref = source_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + source_ = s; + return s; + } else { + return (String) ref; + } + } + /** + *
+     * URI-reference
+     * 
+ * + * string source = 2; + * @return The bytes for source. + */ + public com.google.protobuf.ByteString + getSourceBytes() { + Object ref = source_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + source_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+     * URI-reference
+     * 
+ * + * string source = 2; + * @param value The source to set. + * @return This builder for chaining. + */ + public Builder setSource( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + source_ = value; + onChanged(); + return this; + } + /** + *
+     * URI-reference
+     * 
+ * + * string source = 2; + * @return This builder for chaining. + */ + public Builder clearSource() { + + source_ = getDefaultInstance().getSource(); + onChanged(); + return this; + } + /** + *
+     * URI-reference
+     * 
+ * + * string source = 2; + * @param value The bytes for source to set. + * @return This builder for chaining. + */ + public Builder setSourceBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + source_ = value; + onChanged(); + return this; + } + + private Object specVersion_ = ""; + /** + * string spec_version = 3; + * @return The specVersion. + */ + public String getSpecVersion() { + Object ref = specVersion_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + specVersion_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string spec_version = 3; + * @return The bytes for specVersion. + */ + public com.google.protobuf.ByteString + getSpecVersionBytes() { + Object ref = specVersion_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + specVersion_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string spec_version = 3; + * @param value The specVersion to set. + * @return This builder for chaining. + */ + public Builder setSpecVersion( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + specVersion_ = value; + onChanged(); + return this; + } + /** + * string spec_version = 3; + * @return This builder for chaining. + */ + public Builder clearSpecVersion() { + + specVersion_ = getDefaultInstance().getSpecVersion(); + onChanged(); + return this; + } + /** + * string spec_version = 3; + * @param value The bytes for specVersion to set. + * @return This builder for chaining. + */ + public Builder setSpecVersionBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + specVersion_ = value; + onChanged(); + return this; + } + + private Object type_ = ""; + /** + * string type = 4; + * @return The type. + */ + public String getType() { + Object ref = type_; + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + type_ = s; + return s; + } else { + return (String) ref; + } + } + /** + * string type = 4; + * @return The bytes for type. + */ + public com.google.protobuf.ByteString + getTypeBytes() { + Object ref = type_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + type_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string type = 4; + * @param value The type to set. + * @return This builder for chaining. + */ + public Builder setType( + String value) { + if (value == null) { + throw new NullPointerException(); + } + + type_ = value; + onChanged(); + return this; + } + /** + * string type = 4; + * @return This builder for chaining. + */ + public Builder clearType() { + + type_ = getDefaultInstance().getType(); + onChanged(); + return this; + } + /** + * string type = 4; + * @param value The bytes for type to set. + * @return This builder for chaining. + */ + public Builder setTypeBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + type_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.MapField< + String, CloudEventAttributeValue> attributes_; + private com.google.protobuf.MapField + internalGetAttributes() { + if (attributes_ == null) { + return com.google.protobuf.MapField.emptyMapField( + AttributesDefaultEntryHolder.defaultEntry); + } + return attributes_; + } + private com.google.protobuf.MapField + internalGetMutableAttributes() { + onChanged();; + if (attributes_ == null) { + attributes_ = com.google.protobuf.MapField.newMapField( + AttributesDefaultEntryHolder.defaultEntry); + } + if (!attributes_.isMutable()) { + attributes_ = attributes_.copy(); + } + return attributes_; + } + + public int getAttributesCount() { + return internalGetAttributes().getMap().size(); + } + /** + *
+     * Optional & Extension Attributes
+     * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + + @Override + public boolean containsAttributes( + String key) { + if (key == null) { throw new NullPointerException("map key"); } + return internalGetAttributes().getMap().containsKey(key); + } + /** + * Use {@link #getAttributesMap()} instead. + */ + @Override + @Deprecated + public java.util.Map getAttributes() { + return getAttributesMap(); + } + /** + *
+     * Optional & Extension Attributes
+     * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + @Override + + public java.util.Map getAttributesMap() { + return internalGetAttributes().getMap(); + } + /** + *
+     * Optional & Extension Attributes
+     * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + @Override + + public CloudEventAttributeValue getAttributesOrDefault( + String key, + CloudEventAttributeValue defaultValue) { + if (key == null) { throw new NullPointerException("map key"); } + java.util.Map map = + internalGetAttributes().getMap(); + return map.containsKey(key) ? map.get(key) : defaultValue; + } + /** + *
+     * Optional & Extension Attributes
+     * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + @Override + + public CloudEventAttributeValue getAttributesOrThrow( + String key) { + if (key == null) { throw new NullPointerException("map key"); } + java.util.Map map = + internalGetAttributes().getMap(); + if (!map.containsKey(key)) { + throw new IllegalArgumentException(); + } + return map.get(key); + } + + public Builder clearAttributes() { + internalGetMutableAttributes().getMutableMap() + .clear(); + return this; + } + /** + *
+     * Optional & Extension Attributes
+     * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + + public Builder removeAttributes( + String key) { + if (key == null) { throw new NullPointerException("map key"); } + internalGetMutableAttributes().getMutableMap() + .remove(key); + return this; + } + /** + * Use alternate mutation accessors instead. + */ + @Deprecated + public java.util.Map + getMutableAttributes() { + return internalGetMutableAttributes().getMutableMap(); + } + /** + *
+     * Optional & Extension Attributes
+     * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + public Builder putAttributes( + String key, + CloudEventAttributeValue value) { + if (key == null) { throw new NullPointerException("map key"); } + if (value == null) { + throw new NullPointerException("map value"); +} + + internalGetMutableAttributes().getMutableMap() + .put(key, value); + return this; + } + /** + *
+     * Optional & Extension Attributes
+     * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + + public Builder putAllAttributes( + java.util.Map values) { + internalGetMutableAttributes().getMutableMap() + .putAll(values); + return this; + } + + /** + * bytes binary_data = 6; + * @return Whether the binaryData field is set. + */ + public boolean hasBinaryData() { + return dataCase_ == 6; + } + /** + * bytes binary_data = 6; + * @return The binaryData. + */ + public com.google.protobuf.ByteString getBinaryData() { + if (dataCase_ == 6) { + return (com.google.protobuf.ByteString) data_; + } + return com.google.protobuf.ByteString.EMPTY; + } + /** + * bytes binary_data = 6; + * @param value The binaryData to set. + * @return This builder for chaining. + */ + public Builder setBinaryData(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + dataCase_ = 6; + data_ = value; + onChanged(); + return this; + } + /** + * bytes binary_data = 6; + * @return This builder for chaining. + */ + public Builder clearBinaryData() { + if (dataCase_ == 6) { + dataCase_ = 0; + data_ = null; + onChanged(); + } + return this; + } + + /** + * string text_data = 7; + * @return Whether the textData field is set. + */ + @Override + public boolean hasTextData() { + return dataCase_ == 7; + } + /** + * string text_data = 7; + * @return The textData. + */ + @Override + public String getTextData() { + Object ref = ""; + if (dataCase_ == 7) { + ref = data_; + } + if (!(ref instanceof String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + String s = bs.toStringUtf8(); + if (dataCase_ == 7) { + data_ = s; + } + return s; + } else { + return (String) ref; + } + } + /** + * string text_data = 7; + * @return The bytes for textData. + */ + @Override + public com.google.protobuf.ByteString + getTextDataBytes() { + Object ref = ""; + if (dataCase_ == 7) { + ref = data_; + } + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (String) ref); + if (dataCase_ == 7) { + data_ = b; + } + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string text_data = 7; + * @param value The textData to set. + * @return This builder for chaining. + */ + public Builder setTextData( + String value) { + if (value == null) { + throw new NullPointerException(); + } + dataCase_ = 7; + data_ = value; + onChanged(); + return this; + } + /** + * string text_data = 7; + * @return This builder for chaining. + */ + public Builder clearTextData() { + if (dataCase_ == 7) { + dataCase_ = 0; + data_ = null; + onChanged(); + } + return this; + } + /** + * string text_data = 7; + * @param value The bytes for textData to set. + * @return This builder for chaining. + */ + public Builder setTextDataBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + dataCase_ = 7; + data_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> protoDataBuilder_; + /** + * .google.protobuf.Any proto_data = 8; + * @return Whether the protoData field is set. + */ + @Override + public boolean hasProtoData() { + return dataCase_ == 8; + } + /** + * .google.protobuf.Any proto_data = 8; + * @return The protoData. + */ + @Override + public com.google.protobuf.Any getProtoData() { + if (protoDataBuilder_ == null) { + if (dataCase_ == 8) { + return (com.google.protobuf.Any) data_; + } + return com.google.protobuf.Any.getDefaultInstance(); + } else { + if (dataCase_ == 8) { + return protoDataBuilder_.getMessage(); + } + return com.google.protobuf.Any.getDefaultInstance(); + } + } + /** + * .google.protobuf.Any proto_data = 8; + */ + public Builder setProtoData(com.google.protobuf.Any value) { + if (protoDataBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + data_ = value; + onChanged(); + } else { + protoDataBuilder_.setMessage(value); + } + dataCase_ = 8; + return this; + } + /** + * .google.protobuf.Any proto_data = 8; + */ + public Builder setProtoData( + com.google.protobuf.Any.Builder builderForValue) { + if (protoDataBuilder_ == null) { + data_ = builderForValue.build(); + onChanged(); + } else { + protoDataBuilder_.setMessage(builderForValue.build()); + } + dataCase_ = 8; + return this; + } + /** + * .google.protobuf.Any proto_data = 8; + */ + public Builder mergeProtoData(com.google.protobuf.Any value) { + if (protoDataBuilder_ == null) { + if (dataCase_ == 8 && + data_ != com.google.protobuf.Any.getDefaultInstance()) { + data_ = com.google.protobuf.Any.newBuilder((com.google.protobuf.Any) data_) + .mergeFrom(value).buildPartial(); + } else { + data_ = value; + } + onChanged(); + } else { + if (dataCase_ == 8) { + protoDataBuilder_.mergeFrom(value); + } else { + protoDataBuilder_.setMessage(value); + } + } + dataCase_ = 8; + return this; + } + /** + * .google.protobuf.Any proto_data = 8; + */ + public Builder clearProtoData() { + if (protoDataBuilder_ == null) { + if (dataCase_ == 8) { + dataCase_ = 0; + data_ = null; + onChanged(); + } + } else { + if (dataCase_ == 8) { + dataCase_ = 0; + data_ = null; + } + protoDataBuilder_.clear(); + } + return this; + } + /** + * .google.protobuf.Any proto_data = 8; + */ + public com.google.protobuf.Any.Builder getProtoDataBuilder() { + return getProtoDataFieldBuilder().getBuilder(); + } + /** + * .google.protobuf.Any proto_data = 8; + */ + @Override + public com.google.protobuf.AnyOrBuilder getProtoDataOrBuilder() { + if ((dataCase_ == 8) && (protoDataBuilder_ != null)) { + return protoDataBuilder_.getMessageOrBuilder(); + } else { + if (dataCase_ == 8) { + return (com.google.protobuf.Any) data_; + } + return com.google.protobuf.Any.getDefaultInstance(); + } + } + /** + * .google.protobuf.Any proto_data = 8; + */ + private com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> + getProtoDataFieldBuilder() { + if (protoDataBuilder_ == null) { + if (!(dataCase_ == 8)) { + data_ = com.google.protobuf.Any.getDefaultInstance(); + } + protoDataBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder>( + (com.google.protobuf.Any) data_, + getParentForChildren(), + isClean()); + data_ = null; + } + dataCase_ = 8; + onChanged();; + return protoDataBuilder_; + } + @Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:org.apache.eventmesh.cloudevents.v1.CloudEvent) + } + + // @@protoc_insertion_point(class_scope:org.apache.eventmesh.cloudevents.v1.CloudEvent) + private static final CloudEvent DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new CloudEvent(); + } + + public static CloudEvent getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @Override + public CloudEvent parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CloudEvent(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @Override + public CloudEvent getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEventBatch.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEventBatch.java new file mode 100644 index 0000000000..5d541ec974 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEventBatch.java @@ -0,0 +1,789 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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-cloudevents.proto + +package org.apache.eventmesh.common.protocol.grpc.cloudevents; + +/** + * Protobuf type {@code org.apache.eventmesh.cloudevents.v1.CloudEventBatch} + */ +public final class CloudEventBatch extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:org.apache.eventmesh.cloudevents.v1.CloudEventBatch) + CloudEventBatchOrBuilder { +private static final long serialVersionUID = 0L; + // Use CloudEventBatch.newBuilder() to construct. + private CloudEventBatch(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private CloudEventBatch() { + events_ = java.util.Collections.emptyList(); + } + + @Override + @SuppressWarnings({"unused"}) + protected Object newInstance( + UnusedPrivateParameter unused) { + return new CloudEventBatch(); + } + + @Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CloudEventBatch( + 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; + case 10: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + events_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + events_.add( + input.readMessage(CloudEvent.parser(), extensionRegistry)); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + events_ = java.util.Collections.unmodifiableList(events_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_descriptor; + } + + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_fieldAccessorTable + .ensureFieldAccessorsInitialized( + CloudEventBatch.class, Builder.class); + } + + public static final int EVENTS_FIELD_NUMBER = 1; + private java.util.List events_; + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + @Override + public java.util.List getEventsList() { + return events_; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + @Override + public java.util.List + getEventsOrBuilderList() { + return events_; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + @Override + public int getEventsCount() { + return events_.size(); + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + @Override + public CloudEvent getEvents(int index) { + return events_.get(index); + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + @Override + public CloudEventOrBuilder getEventsOrBuilder( + int index) { + return events_.get(index); + } + + private byte memoizedIsInitialized = -1; + @Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < events_.size(); i++) { + output.writeMessage(1, events_.get(i)); + } + unknownFields.writeTo(output); + } + + @Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < events_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, events_.get(i)); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @Override + public boolean equals(final Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof CloudEventBatch)) { + return super.equals(obj); + } + CloudEventBatch other = (CloudEventBatch) obj; + + if (!getEventsList() + .equals(other.getEventsList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getEventsCount() > 0) { + hash = (37 * hash) + EVENTS_FIELD_NUMBER; + hash = (53 * hash) + getEventsList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static CloudEventBatch parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static CloudEventBatch parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static CloudEventBatch parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static CloudEventBatch parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static CloudEventBatch parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static CloudEventBatch parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static CloudEventBatch parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static CloudEventBatch 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 CloudEventBatch parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static CloudEventBatch 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 CloudEventBatch parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static CloudEventBatch parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(CloudEventBatch prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @Override + 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 org.apache.eventmesh.cloudevents.v1.CloudEventBatch} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:org.apache.eventmesh.cloudevents.v1.CloudEventBatch) + CloudEventBatchOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_descriptor; + } + + @Override + protected FieldAccessorTable + internalGetFieldAccessorTable() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_fieldAccessorTable + .ensureFieldAccessorsInitialized( + CloudEventBatch.class, Builder.class); + } + + // Construct using org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getEventsFieldBuilder(); + } + } + @Override + public Builder clear() { + super.clear(); + if (eventsBuilder_ == null) { + events_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + eventsBuilder_.clear(); + } + return this; + } + + @Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return EventMeshCloudEvents.internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_descriptor; + } + + @Override + public CloudEventBatch getDefaultInstanceForType() { + return CloudEventBatch.getDefaultInstance(); + } + + @Override + public CloudEventBatch build() { + CloudEventBatch result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @Override + public CloudEventBatch buildPartial() { + CloudEventBatch result = new CloudEventBatch(this); + int from_bitField0_ = bitField0_; + if (eventsBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + events_ = java.util.Collections.unmodifiableList(events_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.events_ = events_; + } else { + result.events_ = eventsBuilder_.build(); + } + onBuilt(); + return result; + } + + @Override + public Builder clone() { + return super.clone(); + } + @Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return super.setField(field, value); + } + @Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return super.setRepeatedField(field, index, value); + } + @Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return super.addRepeatedField(field, value); + } + @Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof CloudEventBatch) { + return mergeFrom((CloudEventBatch)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(CloudEventBatch other) { + if (other == CloudEventBatch.getDefaultInstance()) return this; + if (eventsBuilder_ == null) { + if (!other.events_.isEmpty()) { + if (events_.isEmpty()) { + events_ = other.events_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureEventsIsMutable(); + events_.addAll(other.events_); + } + onChanged(); + } + } else { + if (!other.events_.isEmpty()) { + if (eventsBuilder_.isEmpty()) { + eventsBuilder_.dispose(); + eventsBuilder_ = null; + events_ = other.events_; + bitField0_ = (bitField0_ & ~0x00000001); + eventsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getEventsFieldBuilder() : null; + } else { + eventsBuilder_.addAllMessages(other.events_); + } + } + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @Override + public final boolean isInitialized() { + return true; + } + + @Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + CloudEventBatch parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (CloudEventBatch) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.util.List events_ = + java.util.Collections.emptyList(); + private void ensureEventsIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + events_ = new java.util.ArrayList(events_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + CloudEvent, CloudEvent.Builder, CloudEventOrBuilder> eventsBuilder_; + + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public java.util.List getEventsList() { + if (eventsBuilder_ == null) { + return java.util.Collections.unmodifiableList(events_); + } else { + return eventsBuilder_.getMessageList(); + } + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public int getEventsCount() { + if (eventsBuilder_ == null) { + return events_.size(); + } else { + return eventsBuilder_.getCount(); + } + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public CloudEvent getEvents(int index) { + if (eventsBuilder_ == null) { + return events_.get(index); + } else { + return eventsBuilder_.getMessage(index); + } + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public Builder setEvents( + int index, CloudEvent value) { + if (eventsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureEventsIsMutable(); + events_.set(index, value); + onChanged(); + } else { + eventsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public Builder setEvents( + int index, CloudEvent.Builder builderForValue) { + if (eventsBuilder_ == null) { + ensureEventsIsMutable(); + events_.set(index, builderForValue.build()); + onChanged(); + } else { + eventsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public Builder addEvents(CloudEvent value) { + if (eventsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureEventsIsMutable(); + events_.add(value); + onChanged(); + } else { + eventsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public Builder addEvents( + int index, CloudEvent value) { + if (eventsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureEventsIsMutable(); + events_.add(index, value); + onChanged(); + } else { + eventsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public Builder addEvents( + CloudEvent.Builder builderForValue) { + if (eventsBuilder_ == null) { + ensureEventsIsMutable(); + events_.add(builderForValue.build()); + onChanged(); + } else { + eventsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public Builder addEvents( + int index, CloudEvent.Builder builderForValue) { + if (eventsBuilder_ == null) { + ensureEventsIsMutable(); + events_.add(index, builderForValue.build()); + onChanged(); + } else { + eventsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public Builder addAllEvents( + Iterable values) { + if (eventsBuilder_ == null) { + ensureEventsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, events_); + onChanged(); + } else { + eventsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public Builder clearEvents() { + if (eventsBuilder_ == null) { + events_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + eventsBuilder_.clear(); + } + return this; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public Builder removeEvents(int index) { + if (eventsBuilder_ == null) { + ensureEventsIsMutable(); + events_.remove(index); + onChanged(); + } else { + eventsBuilder_.remove(index); + } + return this; + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public CloudEvent.Builder getEventsBuilder( + int index) { + return getEventsFieldBuilder().getBuilder(index); + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public CloudEventOrBuilder getEventsOrBuilder( + int index) { + if (eventsBuilder_ == null) { + return events_.get(index); } else { + return eventsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public java.util.List + getEventsOrBuilderList() { + if (eventsBuilder_ != null) { + return eventsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(events_); + } + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public CloudEvent.Builder addEventsBuilder() { + return getEventsFieldBuilder().addBuilder( + CloudEvent.getDefaultInstance()); + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public CloudEvent.Builder addEventsBuilder( + int index) { + return getEventsFieldBuilder().addBuilder( + index, CloudEvent.getDefaultInstance()); + } + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + public java.util.List + getEventsBuilderList() { + return getEventsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + CloudEvent, CloudEvent.Builder, CloudEventOrBuilder> + getEventsFieldBuilder() { + if (eventsBuilder_ == null) { + eventsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + CloudEvent, CloudEvent.Builder, CloudEventOrBuilder>( + events_, + ((bitField0_ & 0x00000001) != 0), + getParentForChildren(), + isClean()); + events_ = null; + } + return eventsBuilder_; + } + @Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:org.apache.eventmesh.cloudevents.v1.CloudEventBatch) + } + + // @@protoc_insertion_point(class_scope:org.apache.eventmesh.cloudevents.v1.CloudEventBatch) + private static final CloudEventBatch DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new CloudEventBatch(); + } + + public static CloudEventBatch getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @Override + public CloudEventBatch parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CloudEventBatch(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @Override + public CloudEventBatch getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEventBatchOrBuilder.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEventBatchOrBuilder.java new file mode 100644 index 0000000000..5f3256d6fa --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEventBatchOrBuilder.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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-cloudevents.proto + +package org.apache.eventmesh.common.protocol.grpc.cloudevents; + +public interface CloudEventBatchOrBuilder extends + // @@protoc_insertion_point(interface_extends:org.apache.eventmesh.cloudevents.v1.CloudEventBatch) + com.google.protobuf.MessageOrBuilder { + + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + java.util.List + getEventsList(); + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + CloudEvent getEvents(int index); + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + int getEventsCount(); + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + java.util.List + getEventsOrBuilderList(); + /** + * repeated .org.apache.eventmesh.cloudevents.v1.CloudEvent events = 1; + */ + CloudEventOrBuilder getEventsOrBuilder( + int index); +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEventOrBuilder.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEventOrBuilder.java new file mode 100644 index 0000000000..a375b43a89 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/CloudEventOrBuilder.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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-cloudevents.proto + +package org.apache.eventmesh.common.protocol.grpc.cloudevents; + +public interface CloudEventOrBuilder extends + // @@protoc_insertion_point(interface_extends:org.apache.eventmesh.cloudevents.v1.CloudEvent) + com.google.protobuf.MessageOrBuilder { + + /** + *
+   * Required Attributes
+   * 
+ * + * string id = 1; + * @return The id. + */ + String getId(); + /** + *
+   * Required Attributes
+   * 
+ * + * string id = 1; + * @return The bytes for id. + */ + com.google.protobuf.ByteString + getIdBytes(); + + /** + *
+   * URI-reference
+   * 
+ * + * string source = 2; + * @return The source. + */ + String getSource(); + /** + *
+   * URI-reference
+   * 
+ * + * string source = 2; + * @return The bytes for source. + */ + com.google.protobuf.ByteString + getSourceBytes(); + + /** + * string spec_version = 3; + * @return The specVersion. + */ + String getSpecVersion(); + /** + * string spec_version = 3; + * @return The bytes for specVersion. + */ + com.google.protobuf.ByteString + getSpecVersionBytes(); + + /** + * string type = 4; + * @return The type. + */ + String getType(); + /** + * string type = 4; + * @return The bytes for type. + */ + com.google.protobuf.ByteString + getTypeBytes(); + + /** + *
+   * Optional & Extension Attributes
+   * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + int getAttributesCount(); + /** + *
+   * Optional & Extension Attributes
+   * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + boolean containsAttributes( + String key); + /** + * Use {@link #getAttributesMap()} instead. + */ + @Deprecated + java.util.Map + getAttributes(); + /** + *
+   * Optional & Extension Attributes
+   * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + java.util.Map + getAttributesMap(); + /** + *
+   * Optional & Extension Attributes
+   * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + + /* nullable */ +CloudEvent.CloudEventAttributeValue getAttributesOrDefault( + String key, + /* nullable */ +CloudEvent.CloudEventAttributeValue defaultValue); + /** + *
+   * Optional & Extension Attributes
+   * 
+ * + * map<string, .org.apache.eventmesh.cloudevents.v1.CloudEvent.CloudEventAttributeValue> attributes = 5; + */ + + CloudEvent.CloudEventAttributeValue getAttributesOrThrow( + String key); + + /** + * bytes binary_data = 6; + * @return Whether the binaryData field is set. + */ + boolean hasBinaryData(); + /** + * bytes binary_data = 6; + * @return The binaryData. + */ + com.google.protobuf.ByteString getBinaryData(); + + /** + * string text_data = 7; + * @return Whether the textData field is set. + */ + boolean hasTextData(); + /** + * string text_data = 7; + * @return The textData. + */ + String getTextData(); + /** + * string text_data = 7; + * @return The bytes for textData. + */ + com.google.protobuf.ByteString + getTextDataBytes(); + + /** + * .google.protobuf.Any proto_data = 8; + * @return Whether the protoData field is set. + */ + boolean hasProtoData(); + /** + * .google.protobuf.Any proto_data = 8; + * @return The protoData. + */ + com.google.protobuf.Any getProtoData(); + /** + * .google.protobuf.Any proto_data = 8; + */ + com.google.protobuf.AnyOrBuilder getProtoDataOrBuilder(); + + public CloudEvent.DataCase getDataCase(); +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/ConsumerServiceGrpc.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/ConsumerServiceGrpc.java new file mode 100644 index 0000000000..d3f25f558e --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/ConsumerServiceGrpc.java @@ -0,0 +1,443 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.cloudevents; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + */ +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.43.2)", + comments = "Source: eventmesh-service.proto") +@io.grpc.stub.annotations.GrpcGenerated +public final class ConsumerServiceGrpc { + + private ConsumerServiceGrpc() {} + + public static final String SERVICE_NAME = "org.apache.eventmesh.cloudevents.v1.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 = CloudEvent.class, + responseType = CloudEvent.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(SERVICE_NAME, "subscribe")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.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 = CloudEvent.class, + responseType = CloudEvent.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(SERVICE_NAME, "subscribeStream")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.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 = CloudEvent.class, + responseType = CloudEvent.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(SERVICE_NAME, "unsubscribe")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.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) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public ConsumerServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new ConsumerServiceStub(channel, callOptions); + } + }; + return ConsumerServiceStub.newStub(factory, 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) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public ConsumerServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new ConsumerServiceBlockingStub(channel, callOptions); + } + }; + return ConsumerServiceBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static ConsumerServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public ConsumerServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new ConsumerServiceFutureStub(channel, callOptions); + } + }; + return ConsumerServiceFutureStub.newStub(factory, 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(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.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 io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getSubscribeStreamMethod(), responseObserver); + } + + /** + */ + public void unsubscribe(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnsubscribeMethod(), responseObserver); + } + + @Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getSubscribeMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + CloudEvent, + CloudEvent>( + this, METHODID_SUBSCRIBE))) + .addMethod( + getSubscribeStreamMethod(), + io.grpc.stub.ServerCalls.asyncBidiStreamingCall( + new MethodHandlers< + CloudEvent, + CloudEvent>( + this, METHODID_SUBSCRIBE_STREAM))) + .addMethod( + getUnsubscribeMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + CloudEvent, + CloudEvent>( + this, METHODID_UNSUBSCRIBE))) + .build(); + } + } + + /** + */ + public static final class ConsumerServiceStub extends io.grpc.stub.AbstractAsyncStub { + 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(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.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 io.grpc.stub.ClientCalls.asyncBidiStreamingCall( + getChannel().newCall(getSubscribeStreamMethod(), getCallOptions()), responseObserver); + } + + /** + */ + public void unsubscribe(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getUnsubscribeMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + */ + public static final class ConsumerServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + 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 CloudEvent subscribe(CloudEvent request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getSubscribeMethod(), getCallOptions(), request); + } + + /** + */ + public CloudEvent unsubscribe(CloudEvent request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getUnsubscribeMethod(), getCallOptions(), request); + } + } + + /** + */ + public static final class ConsumerServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + 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( + CloudEvent request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getSubscribeMethod(), getCallOptions()), request); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture unsubscribe( + CloudEvent request) { + return io.grpc.stub.ClientCalls.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((CloudEvent) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_UNSUBSCRIBE: + serviceImpl.unsubscribe((CloudEvent) 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 EventMeshGrpcService.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/cloudevents/EventMeshCloudEvents.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/EventMeshCloudEvents.java new file mode 100644 index 0000000000..aebe0a06cb --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/EventMeshCloudEvents.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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-cloudevents.proto + +package org.apache.eventmesh.common.protocol.grpc.cloudevents; + +public final class EventMeshCloudEvents { + private EventMeshCloudEvents() {} + 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_org_apache_eventmesh_cloudevents_v1_CloudEvent_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_AttributesEntry_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_AttributesEntry_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + String[] descriptorData = { + "\n\033eventmesh-cloudevents.proto\022#org.apach" + + "e.eventmesh.cloudevents.v1\032\031google/proto" + + "buf/any.proto\032\037google/protobuf/timestamp" + + ".proto\"\324\004\n\nCloudEvent\022\n\n\002id\030\001 \001(\t\022\016\n\006sou" + + "rce\030\002 \001(\t\022\024\n\014spec_version\030\003 \001(\t\022\014\n\004type\030" + + "\004 \001(\t\022S\n\nattributes\030\005 \003(\0132?.org.apache.e" + + "ventmesh.cloudevents.v1.CloudEvent.Attri" + + "butesEntry\022\025\n\013binary_data\030\006 \001(\014H\000\022\023\n\ttex" + + "t_data\030\007 \001(\tH\000\022*\n\nproto_data\030\010 \001(\0132\024.goo" + + "gle.protobuf.AnyH\000\032{\n\017AttributesEntry\022\013\n" + + "\003key\030\001 \001(\t\022W\n\005value\030\002 \001(\0132H.org.apache.e" + + "ventmesh.cloudevents.v1.CloudEvent.Cloud" + + "EventAttributeValue:\0028\001\032\323\001\n\030CloudEventAt" + + "tributeValue\022\024\n\nce_boolean\030\001 \001(\010H\000\022\024\n\nce" + + "_integer\030\002 \001(\005H\000\022\023\n\tce_string\030\003 \001(\tH\000\022\022\n" + + "\010ce_bytes\030\004 \001(\014H\000\022\020\n\006ce_uri\030\005 \001(\tH\000\022\024\n\nc" + + "e_uri_ref\030\006 \001(\tH\000\0222\n\014ce_timestamp\030\007 \001(\0132" + + "\032.google.protobuf.TimestampH\000B\006\n\004attrB\006\n" + + "\004data\"R\n\017CloudEventBatch\022?\n\006events\030\001 \003(\013" + + "2/.org.apache.eventmesh.cloudevents.v1.C" + + "loudEventBO\n5org.apache.eventmesh.common" + + ".protocol.grpc.cloudeventsB\024EventMeshClo" + + "udEventsP\001b\006proto3" + }; + descriptor = com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + com.google.protobuf.AnyProto.getDescriptor(), + com.google.protobuf.TimestampProto.getDescriptor(), + }); + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_descriptor, + new String[] { "Id", "Source", "SpecVersion", "Type", "Attributes", "BinaryData", "TextData", "ProtoData", "Data", }); + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_AttributesEntry_descriptor = + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_descriptor.getNestedTypes().get(0); + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_AttributesEntry_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_AttributesEntry_descriptor, + new String[] { "Key", "Value", }); + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_descriptor = + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_descriptor.getNestedTypes().get(1); + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEvent_CloudEventAttributeValue_descriptor, + new String[] { "CeBoolean", "CeInteger", "CeString", "CeBytes", "CeUri", "CeUriRef", "CeTimestamp", "Attr", }); + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_org_apache_eventmesh_cloudevents_v1_CloudEventBatch_descriptor, + new String[] { "Events", }); + com.google.protobuf.AnyProto.getDescriptor(); + com.google.protobuf.TimestampProto.getDescriptor(); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/EventMeshGrpcService.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/EventMeshGrpcService.java new file mode 100644 index 0000000000..94dbdbbef3 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/EventMeshGrpcService.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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: eventmesh-service.proto + +package org.apache.eventmesh.common.protocol.grpc.cloudevents; + +public final class EventMeshGrpcService { + private EventMeshGrpcService() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + String[] descriptorData = { + "\n\027eventmesh-service.proto\022#org.apache.ev" + + "entmesh.cloudevents.v1\032\033google/protobuf/" + + "empty.proto\032\033eventmesh-cloudevents.proto" + + "2\246\004\n\020PublisherService\022k\n\007publish\022/.org.a" + + "pache.eventmesh.cloudevents.v1.CloudEven" + + "t\032/.org.apache.eventmesh.cloudevents.v1." + + "CloudEvent\022p\n\014publishReply\022/.org.apache." + + "eventmesh.cloudevents.v1.CloudEvent\032/.or" + + "g.apache.eventmesh.cloudevents.v1.CloudE" + + "vent\022X\n\rpublishOneWay\022/.org.apache.event" + + "mesh.cloudevents.v1.CloudEvent\032\026.google." + + "protobuf.Empty\022u\n\014batchPublish\0224.org.apa" + + "che.eventmesh.cloudevents.v1.CloudEventB" + + "atch\032/.org.apache.eventmesh.cloudevents." + + "v1.CloudEvent\022b\n\022batchPublishOneWay\0224.or" + + "g.apache.eventmesh.cloudevents.v1.CloudE" + + "ventBatch\032\026.google.protobuf.Empty2\352\002\n\017Co" + + "nsumerService\022m\n\tsubscribe\022/.org.apache." + + "eventmesh.cloudevents.v1.CloudEvent\032/.or" + + "g.apache.eventmesh.cloudevents.v1.CloudE" + + "vent\022w\n\017subscribeStream\022/.org.apache.eve" + + "ntmesh.cloudevents.v1.CloudEvent\032/.org.a" + + "pache.eventmesh.cloudevents.v1.CloudEven" + + "t(\0010\001\022o\n\013unsubscribe\022/.org.apache.eventm" + + "esh.cloudevents.v1.CloudEvent\032/.org.apac" + + "he.eventmesh.cloudevents.v1.CloudEvent2\201" + + "\001\n\020HeartbeatService\022m\n\theartbeat\022/.org.a" + + "pache.eventmesh.cloudevents.v1.CloudEven" + + "t\032/.org.apache.eventmesh.cloudevents.v1." + + "CloudEventBO\n5org.apache.eventmesh.commo" + + "n.protocol.grpc.cloudeventsB\024EventMeshGr" + + "pcServiceP\001b\006proto3" + }; + descriptor = com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + com.google.protobuf.EmptyProto.getDescriptor(), + EventMeshCloudEvents.getDescriptor(), + }); + com.google.protobuf.EmptyProto.getDescriptor(); + EventMeshCloudEvents.getDescriptor(); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/HeartbeatServiceGrpc.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/HeartbeatServiceGrpc.java new file mode 100644 index 0000000000..0b347e58c6 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/HeartbeatServiceGrpc.java @@ -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 org.apache.eventmesh.common.protocol.grpc.cloudevents; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + */ +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.43.2)", + comments = "Source: eventmesh-service.proto") +@io.grpc.stub.annotations.GrpcGenerated +public final class HeartbeatServiceGrpc { + + private HeartbeatServiceGrpc() {} + + public static final String SERVICE_NAME = "org.apache.eventmesh.cloudevents.v1.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 = CloudEvent.class, + responseType = CloudEvent.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(SERVICE_NAME, "heartbeat")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.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) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public HeartbeatServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new HeartbeatServiceStub(channel, callOptions); + } + }; + return HeartbeatServiceStub.newStub(factory, 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) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public HeartbeatServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new HeartbeatServiceBlockingStub(channel, callOptions); + } + }; + return HeartbeatServiceBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static HeartbeatServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public HeartbeatServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new HeartbeatServiceFutureStub(channel, callOptions); + } + }; + return HeartbeatServiceFutureStub.newStub(factory, channel); + } + + /** + */ + public static abstract class HeartbeatServiceImplBase implements io.grpc.BindableService { + + /** + */ + public void heartbeat(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getHeartbeatMethod(), responseObserver); + } + + @Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getHeartbeatMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + CloudEvent, + CloudEvent>( + this, METHODID_HEARTBEAT))) + .build(); + } + } + + /** + */ + public static final class HeartbeatServiceStub extends io.grpc.stub.AbstractAsyncStub { + 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(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getHeartbeatMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + */ + public static final class HeartbeatServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + 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 CloudEvent heartbeat(CloudEvent request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getHeartbeatMethod(), getCallOptions(), request); + } + } + + /** + */ + public static final class HeartbeatServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + 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( + CloudEvent request) { + return io.grpc.stub.ClientCalls.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((CloudEvent) 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 EventMeshGrpcService.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/cloudevents/PublisherServiceGrpc.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/PublisherServiceGrpc.java new file mode 100644 index 0000000000..2796402037 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/cloudevents/PublisherServiceGrpc.java @@ -0,0 +1,649 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.cloudevents; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + */ +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.43.2)", + comments = "Source: eventmesh-service.proto") +@io.grpc.stub.annotations.GrpcGenerated +public final class PublisherServiceGrpc { + + private PublisherServiceGrpc() {} + + public static final String SERVICE_NAME = "org.apache.eventmesh.cloudevents.v1.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 = CloudEvent.class, + responseType = CloudEvent.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(SERVICE_NAME, "publish")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.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 = CloudEvent.class, + responseType = CloudEvent.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(SERVICE_NAME, "requestReply")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setSchemaDescriptor(new PublisherServiceMethodDescriptorSupplier("requestReply")) + .build(); + } + } + } + return getRequestReplyMethod; + } + + private static volatile io.grpc.MethodDescriptor getPublishOneWayMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "publishOneWay", + requestType = CloudEvent.class, + responseType = com.google.protobuf.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getPublishOneWayMethod() { + io.grpc.MethodDescriptor getPublishOneWayMethod; + if ((getPublishOneWayMethod = PublisherServiceGrpc.getPublishOneWayMethod) == null) { + synchronized (PublisherServiceGrpc.class) { + if ((getPublishOneWayMethod = PublisherServiceGrpc.getPublishOneWayMethod) == null) { + PublisherServiceGrpc.getPublishOneWayMethod = getPublishOneWayMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "publishOneWay")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + com.google.protobuf.Empty.getDefaultInstance())) + .setSchemaDescriptor(new PublisherServiceMethodDescriptorSupplier("publishOneWay")) + .build(); + } + } + } + return getPublishOneWayMethod; + } + + private static volatile io.grpc.MethodDescriptor getBatchPublishMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "batchPublish", + requestType = CloudEventBatch.class, + responseType = CloudEvent.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(SERVICE_NAME, "batchPublish")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEventBatch.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setSchemaDescriptor(new PublisherServiceMethodDescriptorSupplier("batchPublish")) + .build(); + } + } + } + return getBatchPublishMethod; + } + + private static volatile io.grpc.MethodDescriptor getBatchPublishOneWayMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "batchPublishOneWay", + requestType = CloudEventBatch.class, + responseType = com.google.protobuf.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getBatchPublishOneWayMethod() { + io.grpc.MethodDescriptor getBatchPublishOneWayMethod; + if ((getBatchPublishOneWayMethod = PublisherServiceGrpc.getBatchPublishOneWayMethod) == null) { + synchronized (PublisherServiceGrpc.class) { + if ((getBatchPublishOneWayMethod = PublisherServiceGrpc.getBatchPublishOneWayMethod) == null) { + PublisherServiceGrpc.getBatchPublishOneWayMethod = getBatchPublishOneWayMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "batchPublishOneWay")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEventBatch.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + com.google.protobuf.Empty.getDefaultInstance())) + .setSchemaDescriptor(new PublisherServiceMethodDescriptorSupplier("batchPublishOneWay")) + .build(); + } + } + } + return getBatchPublishOneWayMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static PublisherServiceStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public PublisherServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new PublisherServiceStub(channel, callOptions); + } + }; + return PublisherServiceStub.newStub(factory, 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) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public PublisherServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new PublisherServiceBlockingStub(channel, callOptions); + } + }; + return PublisherServiceBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static PublisherServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @Override + public PublisherServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new PublisherServiceFutureStub(channel, callOptions); + } + }; + return PublisherServiceFutureStub.newStub(factory, channel); + } + + /** + */ + public static abstract class PublisherServiceImplBase implements io.grpc.BindableService { + + /** + *
+     *publish event
+     * 
+ */ + public void publish(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPublishMethod(), responseObserver); + } + + /** + *
+     *publish event with reply
+     * 
+ */ + public void requestReply(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getRequestReplyMethod(), responseObserver); + } + + /** + *
+     *publish event one way
+     * 
+ */ + public void publishOneWay(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPublishOneWayMethod(), responseObserver); + } + + /** + *
+     * publish batch event
+     * 
+ */ + public void batchPublish(CloudEventBatch request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getBatchPublishMethod(), responseObserver); + } + + /** + *
+     *publish batch event one way
+     * 
+ */ + public void batchPublishOneWay(CloudEventBatch request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getBatchPublishOneWayMethod(), responseObserver); + } + + @Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getPublishMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + CloudEvent, + CloudEvent>( + this, METHODID_PUBLISH))) + .addMethod( + getRequestReplyMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + CloudEvent, + CloudEvent>( + this, METHODID_REQUEST_REPLY))) + .addMethod( + getPublishOneWayMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + CloudEvent, + com.google.protobuf.Empty>( + this, METHODID_PUBLISH_ONE_WAY))) + .addMethod( + getBatchPublishMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + CloudEventBatch, + CloudEvent>( + this, METHODID_BATCH_PUBLISH))) + .addMethod( + getBatchPublishOneWayMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + CloudEventBatch, + com.google.protobuf.Empty>( + this, METHODID_BATCH_PUBLISH_ONE_WAY))) + .build(); + } + } + + /** + */ + public static final class PublisherServiceStub extends io.grpc.stub.AbstractAsyncStub { + 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); + } + + /** + *
+     *publish event
+     * 
+ */ + public void publish(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getPublishMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     *publish event with reply
+     * 
+ */ + public void requestReply(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getRequestReplyMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     *publish event one way
+     * 
+ */ + public void publishOneWay(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getPublishOneWayMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * publish batch event
+     * 
+ */ + public void batchPublish(CloudEventBatch request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getBatchPublishMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     *publish batch event one way
+     * 
+ */ + public void batchPublishOneWay(CloudEventBatch request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getBatchPublishOneWayMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + */ + public static final class PublisherServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + 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); + } + + /** + *
+     *publish event
+     * 
+ */ + public CloudEvent publish(CloudEvent request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getPublishMethod(), getCallOptions(), request); + } + + /** + *
+     *publish event with reply
+     * 
+ */ + public CloudEvent requestReply(CloudEvent request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getRequestReplyMethod(), getCallOptions(), request); + } + + /** + *
+     *publish event one way
+     * 
+ */ + public com.google.protobuf.Empty publishOneWay(CloudEvent request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getPublishOneWayMethod(), getCallOptions(), request); + } + + /** + *
+     * publish batch event
+     * 
+ */ + public CloudEvent batchPublish(CloudEventBatch request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getBatchPublishMethod(), getCallOptions(), request); + } + + /** + *
+     *publish batch event one way
+     * 
+ */ + public com.google.protobuf.Empty batchPublishOneWay(CloudEventBatch request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getBatchPublishOneWayMethod(), getCallOptions(), request); + } + } + + /** + */ + public static final class PublisherServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + 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); + } + + /** + *
+     *publish event
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture publish( + CloudEvent request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getPublishMethod(), getCallOptions()), request); + } + + /** + *
+     *publish event with reply
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture requestReply( + CloudEvent request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getRequestReplyMethod(), getCallOptions()), request); + } + + /** + *
+     *publish event one way
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture publishOneWay( + CloudEvent request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getPublishOneWayMethod(), getCallOptions()), request); + } + + /** + *
+     * publish batch event
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture batchPublish( + CloudEventBatch request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getBatchPublishMethod(), getCallOptions()), request); + } + + /** + *
+     *publish batch event one way
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture batchPublishOneWay( + CloudEventBatch request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getBatchPublishOneWayMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_PUBLISH = 0; + private static final int METHODID_REQUEST_REPLY = 1; + private static final int METHODID_PUBLISH_ONE_WAY = 2; + private static final int METHODID_BATCH_PUBLISH = 3; + private static final int METHODID_BATCH_PUBLISH_ONE_WAY = 4; + + 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((CloudEvent) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_REQUEST_REPLY: + serviceImpl.requestReply((CloudEvent) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_PUBLISH_ONE_WAY: + serviceImpl.publishOneWay((CloudEvent) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_BATCH_PUBLISH: + serviceImpl.batchPublish((CloudEventBatch) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_BATCH_PUBLISH_ONE_WAY: + serviceImpl.batchPublishOneWay((CloudEventBatch) 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 EventMeshGrpcService.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(getPublishOneWayMethod()) + .addMethod(getBatchPublishMethod()) + .addMethod(getBatchPublishOneWayMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/BatchEventMeshCloudEventWrapper.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/BatchEventMeshCloudEventWrapper.java new file mode 100644 index 0000000000..a35fbaef47 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/BatchEventMeshCloudEventWrapper.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.grpc.common; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; + +public class BatchEventMeshCloudEventWrapper implements ProtocolTransportObject { + + private static final long serialVersionUID = -3296467364340663768L; + private final CloudEventBatch cloudEventBatch; + + public BatchEventMeshCloudEventWrapper(CloudEventBatch cloudEventBatch) { + this.cloudEventBatch = cloudEventBatch; + } + + public CloudEventBatch getMessage() { + return cloudEventBatch; + } +} 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 deleted file mode 100644 index 7d12024d2d..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/BatchMessageWrapper.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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 static final long serialVersionUID = -3296467364340663768L; - 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/ClientType.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/ClientType.java new file mode 100644 index 0000000000..a2851d26bc --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/ClientType.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.protocol.grpc.common; + +public enum ClientType { + + PUB(1, "Client for publishing"), + + SUB(2, "Client for subscribing"); + + private final int type; + + private final String desc; + + ClientType(int type, String desc) { + this.type = type; + this.desc = desc; + } + + public static ClientType get(int type) { + for (ClientType clientType : ClientType.values()) { + if (clientType.type == type) { + return clientType; + } + } + 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 int getType() { + return type; + } + + public String getDesc() { + return desc; + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/EventMeshCloudEventUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/EventMeshCloudEventUtils.java new file mode 100644 index 0000000000..3ad97d7794 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/EventMeshCloudEventUtils.java @@ -0,0 +1,338 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.Constants; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; + +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; + +public abstract class EventMeshCloudEventUtils { + + private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_DEFAULT); + + private EventMeshCloudEventUtils() { + + } + + private static String getValue(CloudEvent cloudEvent, String defaultValue, String protocolKey) { + try { + return cloudEvent.getAttributesOrThrow(protocolKey).getCeString(); + } catch (Exception e) { + return defaultValue; + } + } + + public static String getEnv(CloudEvent cloudEvent) { + return getEnv(cloudEvent, null); + } + + public static String getEnv(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.ENV); + } + + public static String getIdc(CloudEvent cloudEvent) { + return getIdc(cloudEvent, null); + } + + public static String getIdc(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.IDC); + } + + public static String getSys(CloudEvent cloudEvent) { + return getSys(cloudEvent, null); + } + + public static String getSys(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.SYS); + } + + public static String getPid(CloudEvent cloudEvent) { + return getPid(cloudEvent, null); + } + + public static String getPid(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.PID); + } + + public static String getIp(CloudEvent cloudEvent) { + return getIp(cloudEvent, null); + } + + public static String getIp(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.IP); + } + + public static String getUserName(CloudEvent cloudEvent) { + return getUserName(cloudEvent, null); + } + + public static String getUserName(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.USERNAME); + } + + public static String getPassword(CloudEvent cloudEvent) { + return getPassword(cloudEvent, null); + } + + public static String getPassword(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.PASSWD); + } + + public static String getLanguage(CloudEvent cloudEvent) { + return getLanguage(cloudEvent, null); + } + + public static String getLanguage(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.LANGUAGE); + } + + public static String getProtocolType(CloudEvent cloudEvent) { + return getProtocolType(cloudEvent, null); + } + + public static String getProtocolType(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.PROTOCOL_TYPE); + } + + public static String getProtocolVersion(CloudEvent cloudEvent) { + return getProtocolVersion(cloudEvent, null); + } + + public static String getProtocolVersion(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.PROTOCOL_VERSION); + } + + public static String getProtocolDesc(CloudEvent cloudEvent) { + return getProtocolDesc(cloudEvent, null); + } + + public static String getProtocolDesc(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.PROTOCOL_DESC); + } + + public static String getSeqNum(CloudEvent cloudEvent) { + return getSeqNum(cloudEvent, null); + } + + public static String getSeqNum(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.SEQ_NUM); + } + + public static String getUniqueId(CloudEvent cloudEvent) { + return getUniqueId(cloudEvent, null); + } + + public static String getUniqueId(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.UNIQUE_ID); + } + + public static String getTtl(CloudEvent cloudEvent) { + return getTtl(cloudEvent, null); + } + + public static String getTtl(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.TTL); + } + + public static String getProducerGroup(CloudEvent cloudEvent) { + return getProducerGroup(cloudEvent, null); + } + + public static String getProducerGroup(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.PRODUCERGROUP); + } + + public static String getTag(CloudEvent cloudEvent) { + return getTag(cloudEvent, null); + } + + public static String getTag(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.TAG); + } + + public static String getContentType(CloudEvent cloudEvent) { + return getContentType(cloudEvent, null); + } + + public static String getContentType(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.CONTENT_TYPE); + } + + public static String getSubject(CloudEvent cloudEvent) { + return getSubject(cloudEvent, null); + } + + public static String getSubject(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.SUBJECT); + } + + public static String getDataContentType(CloudEvent cloudEvent) { + return getDataContentType(cloudEvent, null); + } + + public static String getDataContentType(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.DATA_CONTENT_TYPE); + } + + public static String getResponseCode(CloudEvent cloudEvent) { + return getResponseCode(cloudEvent, null); + } + + public static String getResponseCode(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.GRPC_RESPONSE_CODE); + } + + public static String getResponseMessage(CloudEvent cloudEvent) { + return getResponseMessage(cloudEvent, null); + } + + public static String getResponseMessage(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.GRPC_RESPONSE_MESSAGE); + } + + public static String getResponseTime(CloudEvent cloudEvent) { + return getResponseTime(cloudEvent, null); + } + + public static String getResponseTime(CloudEvent cloudEvent, String defaultValue) { + try { + Timestamp timestamp = cloudEvent.getAttributesOrThrow(ProtocolKey.GRPC_RESPONSE_TIME).getCeTimestamp(); + return covertProtoTimestamp(timestamp).toString(); + } catch (Exception e) { + return defaultValue; + } + } + + public static String getCluster(CloudEvent cloudEvent) { + return getCluster(cloudEvent, null); + } + + public static String getCluster(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.PROPERTY_MESSAGE_CLUSTER); + } + + public static String getConsumerGroup(CloudEvent cloudEvent) { + return getConsumerGroup(cloudEvent, null); + } + + public static String getConsumerGroup(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.CONSUMERGROUP); + } + + public static ClientType getClientType(CloudEvent cloudEvent) { + return getClientType(cloudEvent, null); + } + + public static ClientType getClientType(CloudEvent cloudEvent, ClientType defaultValue) { + try { + int type = cloudEvent.getAttributesOrThrow(ProtocolKey.CLIENT_TYPE).getCeInteger(); + return ClientType.get(type); + } catch (Exception e) { + return defaultValue; + } + } + + public static String getURL(CloudEvent cloudEvent) { + return getURL(cloudEvent, null); + } + + public static String getURL(CloudEvent cloudEvent, String defaultValue) { + return getValue(cloudEvent, defaultValue, ProtocolKey.URL); + } + + public static String getDataContent(CloudEvent cloudEvent) { + return getDataContent(cloudEvent, null); + } + + public static String getDataContent(final CloudEvent cloudEvent, String defaultValue) { + String dataContentType = getDataContentType(cloudEvent); + if (ProtoSupport.isTextContent(dataContentType)) { + return Optional.of(cloudEvent.getTextData()).get(); + } + if (ProtoSupport.isProtoContent(dataContentType)) { + Any protoData = cloudEvent.getProtoData(); + return protoData == Any.getDefaultInstance() ? defaultValue + : new String(protoData.toByteArray(), Constants.DEFAULT_CHARSET); + } + ByteString binaryData = cloudEvent.getBinaryData(); + return ByteString.EMPTY == binaryData ? defaultValue : binaryData.toStringUtf8(); + + + } + + public static Map getAttributes(final CloudEvent cloudEvent) { + if (Objects.isNull(cloudEvent)) { + return new HashMap<>(0); + } + Map attributesMap = Optional.of(cloudEvent.getAttributesMap()).get(); + Map convertedAttributes = new HashMap<>(attributesMap.size()); + attributesMap.forEach((key, value) -> { + if (Objects.isNull(value)) { + return; + } + if (value.hasCeBoolean()) { + convertedAttributes.put(key, Boolean.toString(value.getCeBoolean())); + return; + } + if (value.hasCeInteger()) { + convertedAttributes.put(key, Integer.toString(value.getCeInteger())); + return; + } + if (value.hasCeString()) { + convertedAttributes.put(key, value.getCeString()); + return; + } + if (value.hasCeBytes()) { + convertedAttributes.put(key, value.getCeBytes().toString(Constants.DEFAULT_CHARSET)); + return; + } + if (value.hasCeUri()) { + convertedAttributes.put(key, value.getCeUri()); + return; + } + if (value.hasCeUriRef()) { + convertedAttributes.put(key, value.getCeUriRef()); + return; + } + if (value.hasCeTimestamp()) { + OffsetDateTime offsetDateTime = covertProtoTimestamp(value.getCeTimestamp()); + convertedAttributes.put(key, dateTimeFormatter.format(offsetDateTime.toLocalDateTime())); + } + }); + return convertedAttributes; + } + + private static OffsetDateTime covertProtoTimestamp(com.google.protobuf.Timestamp timestamp) { + Instant instant = Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos()); + return instant.atOffset(ZoneOffset.UTC); + } + +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/EventMeshCloudEventWrapper.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/EventMeshCloudEventWrapper.java new file mode 100644 index 0000000000..69b44128a1 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/EventMeshCloudEventWrapper.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.common.protocol.grpc.common; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; + +public class EventMeshCloudEventWrapper implements ProtocolTransportObject { + + private static final long serialVersionUID = 4562321593749195797L; + + private final CloudEvent cloudEvent; + + public EventMeshCloudEventWrapper(CloudEvent cloudEvent) { + this.cloudEvent = cloudEvent; + } + + public CloudEvent getMessage() { + return cloudEvent; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/GrpcType.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/GrpcType.java similarity index 91% rename from eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/GrpcType.java rename to eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/GrpcType.java index 507942a5f5..81317310c6 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/consumer/consumergroup/GrpcType.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/GrpcType.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup; +package org.apache.eventmesh.common.protocol.grpc.common; public enum GrpcType { WEBHOOK, STREAM diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/ProtoSupport.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/ProtoSupport.java new file mode 100644 index 0000000000..e6fc5515db --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/ProtoSupport.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.common.protocol.grpc.common; + +public class ProtoSupport { + + private ProtoSupport() { + + } + + public static boolean isTextContent(String contentType) { + + if (contentType == null) { + return false; + } + + return contentType.startsWith("text/") + || "application/json".equals(contentType) + || "application/xml".equals(contentType) + || contentType.endsWith("+json") + || contentType.endsWith("+xml") + ; + } + + public static boolean isProtoContent(String contentType) { + if (contentType == null) { + return false; + } + return "application/protobuf".equals(contentType); + } +} 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 index 0294ce1c54..ec47fda44b 100644 --- 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 @@ -19,6 +19,7 @@ public class ProtocolKey { + //EventMesh extensions public static final String ENV = "env"; public static final String IDC = "idc"; public static final String SYS = "sys"; @@ -27,16 +28,44 @@ public class ProtocolKey { 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 CONSUMERGROUP = "consumergroup"; public static final String TAG = "tag"; - public static final String CONTENT_TYPE = "contenttype"; + public static final String PROPERTY_MESSAGE_CLUSTER = "cluster"; + public static final String URL = "url"; + + public static final String CLIENT_TYPE = "clienttype"; + + public static final String GRPC_RESPONSE_CODE = "statuscode"; + public static final String GRPC_RESPONSE_MESSAGE = "responsemessage"; + public static final String GRPC_RESPONSE_TIME = "time"; + + public static final String SUB_MESSAGE_TYPE = "submessagetype"; + public static final String SUB_REPLY_MESSAGE = "subscription_reply"; + + /** + * CloudEvents spec + * + * @see context-attributes + */ + + //Required attributes + public static final String ID = "id"; + public static final String SOURCE = "source"; + public static final String SPECVERSION = "specversion"; + public static final String TYPE = "type"; + + //Optional attributes + public static final String DATA_CONTENT_TYPE = "datacontenttype"; + public static final String DATA_SCHEMA = "dataschema"; + public static final String SUBJECT = "subject"; + public static final String TIME = "time"; + public static final String EVENT_DATA = "eventdata"; } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/Response.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/Response.java new file mode 100644 index 0000000000..965a454371 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/Response.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.grpc.common; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode +@Builder +@ToString +public class Response { + + private String respCode; + + private String respMsg; + + private String respTime; + +} 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 deleted file mode 100644 index 8a70b8f997..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/common/SimpleMessageWrapper.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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 static final long serialVersionUID = 4562321593749195797L; - - 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 index afcb794605..65bbed9edd 100644 --- 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 @@ -24,8 +24,8 @@ public enum StatusCode { 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_HEADER_ERR("6", "eventMesh CloudEvent[header] err, "), + EVENTMESH_PROTOCOL_BODY_ERR("7", "eventMesh CloudEvent[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, "), 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 deleted file mode 100644 index 918754ce55..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/BatchMessage.java +++ /dev/null @@ -1,2453 +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. - */ - -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: eventmesh-client.proto - -package org.apache.eventmesh.common.protocol.grpc.protos; - -import java.util.Objects; - -import com.google.protobuf.ByteString; - -/** - * 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 = -3876605571602481461L; - - // 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: { - producerGroup_ = input.readStringRequireUtf8(); - break; - } - case 26: { - topic_ = input.readStringRequireUtf8(); - 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 = -6677110210488831851L; - - // 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: { - content_ = input.readStringRequireUtf8(); - break; - } - case 18: { - ttl_ = input.readStringRequireUtf8(); - break; - } - case 26: { - uniqueId_ = input.readStringRequireUtf8(); - break; - } - case 34: { - seqNum_ = input.readStringRequireUtf8(); - break; - } - case 42: { - tag_ = input.readStringRequireUtf8(); - 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 String content_; - - /** - * string content = 1; - */ - public String getContent() { - return content_; - } - - /** - * string content = 1; - */ - public com.google.protobuf.ByteString - getContentBytes() { - return ByteString.copyFromUtf8(content_); - } - - public static final int TTL_FIELD_NUMBER = 2; - private volatile String ttl_; - - /** - * string ttl = 2; - */ - public String getTtl() { - return ttl_; - } - - /** - * string ttl = 2; - */ - public com.google.protobuf.ByteString - getTtlBytes() { - return ByteString.copyFromUtf8(ttl_); - } - - public static final int UNIQUEID_FIELD_NUMBER = 3; - private volatile String uniqueId_; - - /** - * string uniqueId = 3; - */ - public String getUniqueId() { - return uniqueId_; - } - - /** - * string uniqueId = 3; - */ - public com.google.protobuf.ByteString - getUniqueIdBytes() { - return ByteString.copyFromUtf8(uniqueId_); - } - - public static final int SEQNUM_FIELD_NUMBER = 4; - private volatile String seqNum_; - - /** - * string seqNum = 4; - */ - public String getSeqNum() { - return seqNum_; - } - - /** - * string seqNum = 4; - */ - public com.google.protobuf.ByteString - getSeqNumBytes() { - return ByteString.copyFromUtf8(seqNum_); - } - - public static final int TAG_FIELD_NUMBER = 5; - private volatile String tag_; - - /** - * string tag = 5; - */ - public String getTag() { - return tag_; - } - - /** - * string tag = 5; - */ - public com.google.protobuf.ByteString - getTagBytes() { - return ByteString.copyFromUtf8(tag_); - } - - 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) { - Objects.requireNonNull(key, "key can not be null"); - - 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) { - Objects.requireNonNull(key, "key can not be null"); - - java.util.Map map = - internalGetProperties().getMap(); - String value = map.get(key); - if (value == null) return defaultValue; - return value; - } - - /** - * map<string, string> properties = 6; - */ - - public String getPropertiesOrThrow( - String key) { - Objects.requireNonNull(key, "key can not be null"); - - 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() { - if (memoizedIsInitialized == 1) return true; - if (memoizedIsInitialized == 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; - - return getContent() - .equals(other.getContent()) - && getTtl() - .equals(other.getTtl()) - && getUniqueId() - .equals(other.getUniqueId()) - && getSeqNum() - .equals(other.getSeqNum()) - && getTag() - .equals(other.getTag()) - && internalGetProperties().equals( - other.internalGetProperties()) - && unknownFields.equals(other.unknownFields); - } - - @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) { - return new Builder(parent); - } - - /** - * 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 String content_ = ""; - - /** - * string content = 1; - */ - public String getContent() { - return content_; - } - - /** - * string content = 1; - */ - public com.google.protobuf.ByteString - getContentBytes() { - return ByteString.copyFromUtf8(content_); - } - - /** - * string content = 1; - */ - public Builder setContent( - String value) { - Objects.requireNonNull(value, "content can not be null"); - - 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) { - Objects.requireNonNull(value, "ContentBytes can not be null"); - checkByteStringIsUtf8(value); - - content_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String ttl_ = ""; - - /** - * string ttl = 2; - */ - public String getTtl() { - return ttl_; - } - - /** - * string ttl = 2; - */ - public com.google.protobuf.ByteString - getTtlBytes() { - return ByteString.copyFromUtf8(ttl_); - } - - /** - * string ttl = 2; - */ - public Builder setTtl( - String value) { - Objects.requireNonNull(value, "ttl can not be null"); - - 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) { - Objects.requireNonNull(value, "TtlBytes can not be null"); - checkByteStringIsUtf8(value); - - ttl_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String uniqueId_ = ""; - - /** - * string uniqueId = 3; - */ - public String getUniqueId() { - return uniqueId_; - } - - /** - * string uniqueId = 3; - */ - public com.google.protobuf.ByteString - getUniqueIdBytes() { - return ByteString.copyFromUtf8(uniqueId_); - } - - /** - * string uniqueId = 3; - */ - public Builder setUniqueId( - String value) { - Objects.requireNonNull(value, "uniqueId_ can not be null"); - - 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) { - Objects.requireNonNull(value, "UniqueIdBytes can not be null"); - checkByteStringIsUtf8(value); - - uniqueId_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String seqNum_ = ""; - - /** - * string seqNum = 4; - */ - public String getSeqNum() { - return seqNum_; - } - - /** - * string seqNum = 4; - */ - public com.google.protobuf.ByteString - getSeqNumBytes() { - return ByteString.copyFromUtf8(seqNum_); - } - - /** - * string seqNum = 4; - */ - public Builder setSeqNum( - String value) { - Objects.requireNonNull(value, "SeqNum can not be null"); - - 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) { - Objects.requireNonNull(value, "SeqNumBytes can not be null"); - checkByteStringIsUtf8(value); - - seqNum_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String tag_ = ""; - - /** - * string tag = 5; - */ - public String getTag() { - return tag_; - } - - /** - * string tag = 5; - */ - public com.google.protobuf.ByteString - getTagBytes() { - return ByteString.copyFromUtf8(tag_); - } - - /** - * string tag = 5; - */ - public Builder setTag( - String value) { - Objects.requireNonNull(value, "tag can not be null"); - - 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) { - Objects.requireNonNull(value, "TagBytes can not be null"); - checkByteStringIsUtf8(value); - - tag_ = value.toStringUtf8(); - 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) { - Objects.requireNonNull(key, "key can not be null"); - - 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) { - Objects.requireNonNull(key, "key can not be null"); - - java.util.Map map = - internalGetProperties().getMap(); - String value = map.get(key); - if (value == null) return defaultValue; - return value; - } - - /** - * map<string, string> properties = 6; - */ - - public String getPropertiesOrThrow( - String key) { - Objects.requireNonNull(key, "key can not be null"); - - 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) { - Objects.requireNonNull(key, "key can not be null"); - - 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) { - Objects.requireNonNull(key, "key can not be null"); - Objects.requireNonNull(value, "value can not be null"); - - 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 String producerGroup_; - - /** - * string producerGroup = 2; - */ - public String getProducerGroup() { - return producerGroup_; - } - - /** - * string producerGroup = 2; - */ - public com.google.protobuf.ByteString - getProducerGroupBytes() { - return ByteString.copyFromUtf8(producerGroup_); - } - - public static final int TOPIC_FIELD_NUMBER = 3; - private volatile String topic_; - - /** - * string topic = 3; - */ - public String getTopic() { - return topic_; - } - - /** - * string topic = 3; - */ - public com.google.protobuf.ByteString - getTopicBytes() { - return ByteString.copyFromUtf8(topic_); - } - - 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() { - if (memoizedIsInitialized == 1) return true; - if (memoizedIsInitialized == 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(MessageItem out: messageItem_) { - output.writeMessage(4, out); - } - unknownFields.writeTo(output); - } - - public int getSerializedSize() { - int size; - if (memoizedSize != -1) return memoizedSize; - size = header_ != null ? - com.google.protobuf.CodedOutputStream.computeMessageSize(1, getHeader()) : 0; - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, producerGroup_); - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, topic_); - size += messageItem_.stream() - .mapToInt(messageItem -> com.google.protobuf.CodedOutputStream.computeMessageSize(4, messageItem)) - .sum(); - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return memoizedSize; - } - - @Override - public boolean equals(final Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof BatchMessage)) { - return super.equals(obj); - } - BatchMessage other = (BatchMessage) obj; - - return (hasHeader() == other.hasHeader()) - && (hasHeader() ? getHeader().equals(other.getHeader()) : true) - && getProducerGroup().equals(other.getProducerGroup()) - && getTopic().equals(other.getTopic()) - && getMessageItemList().equals(other.getMessageItemList()) - && unknownFields.equals(other.unknownFields); - } - - @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 String producerGroup_ = ""; - - /** - * string producerGroup = 2; - */ - public String getProducerGroup() { - return producerGroup_; - } - - /** - * string producerGroup = 2; - */ - public com.google.protobuf.ByteString - getProducerGroupBytes() { - return ByteString.copyFromUtf8(producerGroup_); - } - - /** - * string producerGroup = 2; - */ - public Builder setProducerGroup( - String value) { - Objects.requireNonNull(value, "ProducerGroup can not be null"); - - 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) { - Objects.requireNonNull(value, "ProducerGroupBytes can not be null"); - checkByteStringIsUtf8(value); - - producerGroup_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String topic_ = ""; - - /** - * string topic = 3; - */ - public String getTopic() { - return topic_; - } - - /** - * string topic = 3; - */ - public com.google.protobuf.ByteString - getTopicBytes() { - return ByteString.copyFromUtf8(topic_); - } - - /** - * string topic = 3; - */ - public Builder setTopic( - String value) { - Objects.requireNonNull(value, "Topic can not be null"); - - 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) { - Objects.requireNonNull(value, "TopicBytes can not be null"); - checkByteStringIsUtf8(value); - - topic_ = value.toStringUtf8(); - 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 deleted file mode 100644 index 7f46dd24e9..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/BatchMessageOrBuilder.java +++ /dev/null @@ -1,84 +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. - */ - -// 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 deleted file mode 100644 index 8f55f659d3..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/ConsumerServiceGrpc.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.42.2)", - 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 deleted file mode 100644 index f78053720a..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/EventmeshGrpc.java +++ /dev/null @@ -1,283 +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. - */ - -// 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 deleted file mode 100644 index 72ff62b368..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Heartbeat.java +++ /dev/null @@ -1,1988 +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. - */ - -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: eventmesh-client.proto - -package org.apache.eventmesh.common.protocol.grpc.protos; - -import java.util.Objects; - -import com.google.protobuf.ByteString; - - - -/** - * 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 = -617903330545075556L; - - // 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: { - clientType_ = input.readEnum(); - break; - } - case 26: { - producerGroup_ = input.readStringRequireUtf8(); - break; - } - case 34: { - consumerGroup_ = input.readStringRequireUtf8(); - 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: { - topic_ = input.readStringRequireUtf8(); - break; - } - case 18: { - url_ = input.readStringRequireUtf8(); - 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 String topic_; - - /** - * string topic = 1; - */ - public String getTopic() { - return topic_; - } - - /** - * string topic = 1; - */ - public com.google.protobuf.ByteString getTopicBytes() { - return ByteString.copyFromUtf8(topic_); - } - - public static final int URL_FIELD_NUMBER = 2; - private volatile String url_; - - /** - * string url = 2; - */ - public String getUrl() { - return url_; - } - - /** - * string url = 2; - */ - public com.google.protobuf.ByteString getUrlBytes() { - return ByteString.copyFromUtf8(url_); - } - - private byte memoizedIsInitialized = -1; - - public final boolean isInitialized() { - if (memoizedIsInitialized == 1) return true; - if (memoizedIsInitialized == 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; - - return getTopic().equals(other.getTopic()) - && getUrl().equals(other.getUrl()) - && unknownFields.equals(other.unknownFields); - } - - @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.equals(DEFAULT_INSTANCE) - ? new Builder() : new Builder().mergeFrom(this); - } - - @Override - protected Builder newBuilderForType( - BuilderParent parent) { - return new Builder(parent); - } - - /** - * 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.equals(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 String topic_ = ""; - - /** - * string topic = 1; - */ - public String getTopic() { - return topic_; - } - - /** - * string topic = 1; - */ - public com.google.protobuf.ByteString getTopicBytes() { - return ByteString.copyFromUtf8(topic_); - } - - /** - * string topic = 1; - */ - public Builder setTopic( - String value) { - Objects.requireNonNull(value, "topic can not be null"); - - 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) { - Objects.requireNonNull(value, "TopicBytes can not be null"); - - checkByteStringIsUtf8(value); - - topic_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String url_ = ""; - - /** - * string url = 2; - */ - public String getUrl() { - return url_; - } - - /** - * string url = 2; - */ - public com.google.protobuf.ByteString getUrlBytes() { - return ByteString.copyFromUtf8(url_); - } - - /** - * string url = 2; - */ - public Builder setUrl( - String value) { - Objects.requireNonNull(value, "url can not be null"); - - 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) { - Objects.requireNonNull(value, "UrlBytes can not be null"); - checkByteStringIsUtf8(value); - - url_ = value.toStringUtf8(); - 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 String producerGroup_; - - /** - * string producerGroup = 3; - */ - public String getProducerGroup() { - return producerGroup_; - } - - /** - * string producerGroup = 3; - */ - public com.google.protobuf.ByteString - getProducerGroupBytes() { - return ByteString.copyFromUtf8(producerGroup_); - } - - public static final int CONSUMERGROUP_FIELD_NUMBER = 4; - private volatile String consumerGroup_; - - /** - * string consumerGroup = 4; - */ - public String getConsumerGroup() { - return consumerGroup_; - } - - /** - * string consumerGroup = 4; - */ - public com.google.protobuf.ByteString - getConsumerGroupBytes() { - return ByteString.copyFromUtf8(consumerGroup_); - } - - 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 (HeartbeatItem heartbeatItem : heartbeatItems_) { - output.writeMessage(5, heartbeatItem); - } - 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 (HeartbeatItem heartbeatItem : heartbeatItems_) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(5, heartbeatItem); - } - 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; - - return hasHeader() == other.hasHeader() - && hasHeader() ? getHeader().equals(other.getHeader()) : true - && clientType_ == other.clientType_ - && getProducerGroup().equals(other.getProducerGroup()) - && getConsumerGroup().equals(other.getConsumerGroup()) - && getHeartbeatItemsList().equals(other.getHeartbeatItemsList()) - && unknownFields.equals(other.unknownFields); - } - - @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.equals(DEFAULT_INSTANCE) - ? new Builder() : new Builder().mergeFrom(this); - } - - @Override - protected Builder newBuilderForType( - BuilderParent parent) { - return new Builder(parent); - } - - /** - * 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.equals(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 String producerGroup_ = ""; - - /** - * string producerGroup = 3; - */ - public String getProducerGroup() { - return producerGroup_; - } - - /** - * string producerGroup = 3; - */ - public com.google.protobuf.ByteString - getProducerGroupBytes() { - return ByteString.copyFromUtf8(producerGroup_); - } - - /** - * string producerGroup = 3; - */ - public Builder setProducerGroup( - String value) { - Objects.requireNonNull(value, "ProducerGroup can not be null"); - - 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) { - Objects.requireNonNull(value, "ProducerGroupBytes can not be null"); - checkByteStringIsUtf8(value); - - producerGroup_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String consumerGroup_ = ""; - - /** - * string consumerGroup = 4; - */ - public String getConsumerGroup() { - return consumerGroup_; - } - - /** - * string consumerGroup = 4; - */ - public com.google.protobuf.ByteString - getConsumerGroupBytes() { - return ByteString.copyFromUtf8(consumerGroup_); - } - - /** - * string consumerGroup = 4; - */ - public Builder setConsumerGroup( - String value) { - Objects.requireNonNull(value, "ConsumerGroup can not be null"); - - 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) { - Objects.requireNonNull(value, "ConsumerGroupBytes can not be null"); - checkByteStringIsUtf8(value); - - consumerGroup_ = value.toStringUtf8(); - 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) { - Objects.requireNonNull(value, "HeartbeatItem can not be null"); - 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) { - Objects.requireNonNull(value, "HeartbeatItem can not be null"); - 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) { - Objects.requireNonNull(value, "HeartbeatItem can not be null"); - 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 deleted file mode 100644 index c3cddbdb4b..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/HeartbeatOrBuilder.java +++ /dev/null @@ -1,93 +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. - */ - -// 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 deleted file mode 100644 index dca914b039..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/HeartbeatServiceGrpc.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.42.2)", - 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 deleted file mode 100644 index 20f3a23c17..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/PublisherServiceGrpc.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.42.2)", - 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 deleted file mode 100644 index 21b23be268..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/RequestHeader.java +++ /dev/null @@ -1,1507 +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. - */ - -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: eventmesh-client.proto - -package org.apache.eventmesh.common.protocol.grpc.protos; - -import java.util.Objects; - -import com.google.protobuf.ByteString; - -/** - * 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 = 51630109646794056L; - - // 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(); - Objects.requireNonNull(input, "CodedInputStream can not be null"); - Objects.requireNonNull(extensionRegistry, "ExtensionRegistryLite can not be null"); - - 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: { - env_ = input.readStringRequireUtf8(); - break; - } - case 18: { - region_ = input.readStringRequireUtf8(); - break; - } - case 26: { - idc_ = input.readStringRequireUtf8(); - break; - } - case 34: { - ip_ = input.readStringRequireUtf8(); - break; - } - case 42: { - pid_ = input.readStringRequireUtf8(); - break; - } - case 50: { - sys_ = input.readStringRequireUtf8(); - break; - } - case 58: { - username_ = input.readStringRequireUtf8(); - break; - } - case 66: { - password_ = input.readStringRequireUtf8(); - break; - } - case 74: { - language_ = input.readStringRequireUtf8(); - break; - } - case 82: { - protocolType_ = input.readStringRequireUtf8(); - break; - } - case 90: { - protocolVersion_ = input.readStringRequireUtf8(); - break; - } - case 98: { - protocolDesc_ = input.readStringRequireUtf8(); - 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 String env_; - - /** - * string env = 1; - */ - public String getEnv() { - return env_; - } - - /** - * string env = 1; - */ - public com.google.protobuf.ByteString getEnvBytes() { - return ByteString.copyFromUtf8(env_); - } - - public static final int REGION_FIELD_NUMBER = 2; - private volatile String region_; - - /** - * string region = 2; - */ - public String getRegion() { - return region_; - } - - /** - * string region = 2; - */ - public com.google.protobuf.ByteString getRegionBytes() { - return ByteString.copyFromUtf8(region_); - } - - public static final int IDC_FIELD_NUMBER = 3; - private volatile String idc_; - - /** - * string idc = 3; - */ - public String getIdc() { - return idc_; - } - - /** - * string idc = 3; - */ - public com.google.protobuf.ByteString getIdcBytes() { - return ByteString.copyFromUtf8(idc_); - } - - public static final int IP_FIELD_NUMBER = 4; - private volatile String ip_; - - /** - * string ip = 4; - */ - public String getIp() { - return ip_; - } - - /** - * string ip = 4; - */ - public com.google.protobuf.ByteString getIpBytes() { - return ByteString.copyFromUtf8(ip_); - } - - public static final int PID_FIELD_NUMBER = 5; - private volatile String pid_; - - /** - * string pid = 5; - */ - public String getPid() { - return pid_; - } - - /** - * string pid = 5; - */ - public com.google.protobuf.ByteString getPidBytes() { - return ByteString.copyFromUtf8(pid_); - } - - public static final int SYS_FIELD_NUMBER = 6; - private volatile String sys_; - - /** - * string sys = 6; - */ - public String getSys() { - return sys_; - } - - /** - * string sys = 6; - */ - public com.google.protobuf.ByteString getSysBytes() { - return ByteString.copyFromUtf8(sys_); - } - - public static final int USERNAME_FIELD_NUMBER = 7; - private volatile String username_; - - /** - * string username = 7; - */ - public String getUsername() { - return username_; - } - - /** - * string username = 7; - */ - public com.google.protobuf.ByteString getUsernameBytes() { - return ByteString.copyFromUtf8(username_); - } - - public static final int PASSWORD_FIELD_NUMBER = 8; - private volatile String password_; - - /** - * string password = 8; - */ - public String getPassword() { - return password_; - } - - /** - * string password = 8; - */ - public com.google.protobuf.ByteString - getPasswordBytes() { - return ByteString.copyFromUtf8(password_); - } - - public static final int LANGUAGE_FIELD_NUMBER = 9; - private volatile String language_; - - /** - * string language = 9; - */ - public String getLanguage() { - return language_; - } - - /** - * string language = 9; - */ - public com.google.protobuf.ByteString getLanguageBytes() { - return ByteString.copyFromUtf8(language_); - } - - public static final int PROTOCOLTYPE_FIELD_NUMBER = 10; - private volatile String protocolType_; - - /** - * string protocolType = 10; - */ - public String getProtocolType() { - return protocolType_; - } - - /** - * string protocolType = 10; - */ - public com.google.protobuf.ByteString - getProtocolTypeBytes() { - return ByteString.copyFromUtf8(protocolType_); - } - - public static final int PROTOCOLVERSION_FIELD_NUMBER = 11; - private volatile String protocolVersion_; - - /** - * string protocolVersion = 11; - */ - public String getProtocolVersion() { - return protocolVersion_; - } - - /** - * string protocolVersion = 11; - */ - public com.google.protobuf.ByteString getProtocolVersionBytes() { - return ByteString.copyFromUtf8(protocolVersion_); - } - - public static final int PROTOCOLDESC_FIELD_NUMBER = 12; - private volatile String protocolDesc_; - - /** - * string protocolDesc = 12; - */ - public String getProtocolDesc() { - return protocolDesc_; - } - - /** - * string protocolDesc = 12; - */ - public com.google.protobuf.ByteString getProtocolDescBytes() { - return ByteString.copyFromUtf8(protocolDesc_); - } - - private byte memoizedIsInitialized = -1; - - public final boolean isInitialized() { - if (memoizedIsInitialized == 1) return true; - if (memoizedIsInitialized == 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; - - return getEnv().equals(other.getEnv()) - && getRegion().equals(other.getRegion()) - && getIdc().equals(other.getIdc()) - && getIp().equals(other.getIp()) - && getPid().equals(other.getPid()) - && getSys().equals(other.getSys()) - && getUsername().equals(other.getUsername()) - && getPassword().equals(other.getPassword()) - && getLanguage().equals(other.getLanguage()) - && getProtocolType().equals(other.getProtocolType()) - && getProtocolVersion().equals(other.getProtocolVersion()) - && getProtocolDesc().equals(other.getProtocolDesc()) - && unknownFields.equals(other.unknownFields); - } - - @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) { - return new Builder(parent); - } - - /** - * 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 String env_ = ""; - - /** - * string env = 1; - */ - public String getEnv() { - return env_; - } - - /** - * string env = 1; - */ - public com.google.protobuf.ByteString getEnvBytes() { - return ByteString.copyFromUtf8(env_); - } - - /** - * string env = 1; - */ - public Builder setEnv(String value) { - Objects.requireNonNull(value, "Env can not be null"); - - 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) { - Objects.requireNonNull(value, "EnvBytes can not be null"); - checkByteStringIsUtf8(value); - - env_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String region_ = ""; - - /** - * string region = 2; - */ - public String getRegion() { - return region_; - } - - /** - * string region = 2; - */ - public com.google.protobuf.ByteString getRegionBytes() { - return ByteString.copyFromUtf8(region_); - } - - /** - * string region = 2; - */ - public Builder setRegion( - String value) { - Objects.requireNonNull(value, "Region can not be null"); - - 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) { - Objects.requireNonNull(value, "RegionBytes can not be null"); - checkByteStringIsUtf8(value); - - region_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String idc_ = ""; - - /** - * string idc = 3; - */ - public String getIdc() { - return idc_; - } - - /** - * string idc = 3; - */ - public com.google.protobuf.ByteString getIdcBytes() { - return ByteString.copyFromUtf8(idc_); - } - - /** - * string idc = 3; - */ - public Builder setIdc(String value) { - Objects.requireNonNull(value, "Idc can not be null"); - - 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) { - Objects.requireNonNull(value, "IdcBytes can not be null"); - checkByteStringIsUtf8(value); - - idc_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String ip_ = ""; - - /** - * string ip = 4; - */ - public String getIp() { - return ip_; - } - - /** - * string ip = 4; - */ - public com.google.protobuf.ByteString getIpBytes() { - return ByteString.copyFromUtf8(ip_); - } - - /** - * string ip = 4; - */ - public Builder setIp(String value) { - Objects.requireNonNull(value, "Ip can not be null"); - - 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) { - Objects.requireNonNull(value, "IpBytes can not be null"); - checkByteStringIsUtf8(value); - - ip_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String pid_ = ""; - - /** - * string pid = 5; - */ - public String getPid() { - return pid_; - } - - /** - * string pid = 5; - */ - public com.google.protobuf.ByteString getPidBytes() { - return ByteString.copyFromUtf8(pid_); - } - - /** - * string pid = 5; - */ - public Builder setPid( - String value) { - Objects.requireNonNull(value, "Pid can not be null"); - - 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) { - Objects.requireNonNull(value, "PidBytes can not be null"); - checkByteStringIsUtf8(value); - - pid_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String sys_ = ""; - - /** - * string sys = 6; - */ - public String getSys() { - return sys_; - } - - /** - * string sys = 6; - */ - public com.google.protobuf.ByteString getSysBytes() { - return ByteString.copyFromUtf8(sys_); - } - - /** - * string sys = 6; - */ - public Builder setSys( - String value) { - Objects.requireNonNull(value, "Sys can not be null"); - - 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) { - Objects.requireNonNull(value, "SysBytes can not be null"); - checkByteStringIsUtf8(value); - - sys_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String username_ = ""; - - /** - * string username = 7; - */ - public String getUsername() { - return username_; - } - - /** - * string username = 7; - */ - public com.google.protobuf.ByteString - getUsernameBytes() { - return ByteString.copyFromUtf8(username_); - } - - /** - * string username = 7; - */ - public Builder setUsername( - String value) { - Objects.requireNonNull(value, "Username can not be null"); - - 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) { - Objects.requireNonNull(value, "UsernameBytes can not be null"); - checkByteStringIsUtf8(value); - - username_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String password_ = ""; - - /** - * string password = 8; - */ - public String getPassword() { - return password_; - - } - - /** - * string password = 8; - */ - public com.google.protobuf.ByteString getPasswordBytes() { - return ByteString.copyFromUtf8(password_); - } - - /** - * string password = 8; - */ - public Builder setPassword( - String value) { - Objects.requireNonNull(value, "Password can not be null"); - - 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) { - Objects.requireNonNull(value, "PasswordBytes can not be null"); - - checkByteStringIsUtf8(value); - - password_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String language_ = ""; - - /** - * string language = 9; - */ - public String getLanguage() { - return language_; - } - - /** - * string language = 9; - */ - public com.google.protobuf.ByteString - getLanguageBytes() { - return ByteString.copyFromUtf8(language_); - } - - /** - * string language = 9; - */ - public Builder setLanguage( - String value) { - Objects.requireNonNull(value, "Language can not be null"); - - 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) { - Objects.requireNonNull(value, "LanguageBytes can not be null"); - checkByteStringIsUtf8(value); - - language_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String protocolType_ = ""; - - /** - * string protocolType = 10; - */ - public String getProtocolType() { - return protocolType_; - } - - /** - * string protocolType = 10; - */ - public com.google.protobuf.ByteString - getProtocolTypeBytes() { - return ByteString.copyFromUtf8(protocolType_); - } - - /** - * string protocolType = 10; - */ - public Builder setProtocolType( - String value) { - Objects.requireNonNull(value, "ProtocolType can not be null"); - - 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) { - Objects.requireNonNull(value, "ProtocolTypeBytes can not be null"); - checkByteStringIsUtf8(value); - - protocolType_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String protocolVersion_ = ""; - - /** - * string protocolVersion = 11; - */ - public String getProtocolVersion() { - return protocolVersion_; - } - - /** - * string protocolVersion = 11; - */ - public com.google.protobuf.ByteString - getProtocolVersionBytes() { - return ByteString.copyFromUtf8(protocolVersion_); - } - - /** - * string protocolVersion = 11; - */ - public Builder setProtocolVersion( - String value) { - Objects.requireNonNull(value, "ProtocolVersion can not be null"); - - 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) { - Objects.requireNonNull(value, "ProtocolVersionBytes can not be null"); - checkByteStringIsUtf8(value); - - protocolVersion_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String protocolDesc_ = ""; - - /** - * string protocolDesc = 12; - */ - public String getProtocolDesc() { - return protocolDesc_; - } - - /** - * string protocolDesc = 12; - */ - public com.google.protobuf.ByteString getProtocolDescBytes() { - return ByteString.copyFromUtf8(protocolDesc_); - } - - /** - * string protocolDesc = 12; - */ - public Builder setProtocolDesc( - String value) { - Objects.requireNonNull(value, "ProtocolDesc can not be null"); - - 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) { - Objects.requireNonNull(value, "ProtocolDescBytes can not be null"); - checkByteStringIsUtf8(value); - - protocolDesc_ = value.toStringUtf8(); - 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 deleted file mode 100644 index ec8a176bba..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/RequestHeaderOrBuilder.java +++ /dev/null @@ -1,147 +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. - */ - -// 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 deleted file mode 100644 index e5d810663d..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Response.java +++ /dev/null @@ -1,701 +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. - */ - -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: eventmesh-client.proto - -package org.apache.eventmesh.common.protocol.grpc.protos; - -import java.util.Objects; - -import com.google.protobuf.ByteString; - -/** - * 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 = -6326489945644944331L; - - // 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(); - Objects.requireNonNull(input,"CodedInputStream can not be null"); - Objects.requireNonNull(extensionRegistry,"ExtensionRegistryLite can not be null"); - - 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: { - respCode_ = input.readStringRequireUtf8(); - break; - } - case 18: { - respMsg_ = input.readStringRequireUtf8(); - break; - } - case 26: { - respTime_ = input.readStringRequireUtf8(); - 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 String respCode_; - - /** - * string respCode = 1; - */ - public String getRespCode() { - return respCode_; - } - - /** - * string respCode = 1; - */ - public com.google.protobuf.ByteString getRespCodeBytes() { - return ByteString.copyFromUtf8(respCode_); - } - - public static final int RESPMSG_FIELD_NUMBER = 2; - private volatile String respMsg_; - - /** - * string respMsg = 2; - */ - public String getRespMsg() { - return respMsg_; - } - - /** - * string respMsg = 2; - */ - public com.google.protobuf.ByteString getRespMsgBytes() { - return ByteString.copyFromUtf8(respMsg_); - } - - public static final int RESPTIME_FIELD_NUMBER = 3; - private volatile String respTime_; - - /** - * string respTime = 3; - */ - public String getRespTime() { - return respTime_; - } - - /** - * string respTime = 3; - */ - public com.google.protobuf.ByteString getRespTimeBytes() { - return ByteString.copyFromUtf8(respTime_); - } - - private byte memoizedIsInitialized = -1; - - public final boolean isInitialized() { - if (memoizedIsInitialized == 1) return true; - if (memoizedIsInitialized == 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; - - return getRespCode().equals(other.getRespCode()) - && getRespMsg().equals(other.getRespMsg()) - && getRespTime().equals(other.getRespTime()) - && unknownFields.equals(other.unknownFields); - } - - @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) { - return new Builder(parent); - } - - /** - * 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 String respCode_ = ""; - - /** - * string respCode = 1; - */ - public String getRespCode() { - return respCode_; - } - - /** - * string respCode = 1; - */ - public com.google.protobuf.ByteString - getRespCodeBytes() { - return ByteString.copyFromUtf8(respCode_); - } - - /** - * string respCode = 1; - */ - public Builder setRespCode(String value) { - Objects.requireNonNull(value,"RespCode can not be null"); - - 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) { - Objects.requireNonNull(value,"RespCodeBytes can not be null"); - checkByteStringIsUtf8(value); - - respCode_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String respMsg_ = ""; - - /** - * string respMsg = 2; - */ - public String getRespMsg() { - return respMsg_; - } - - /** - * string respMsg = 2; - */ - public com.google.protobuf.ByteString getRespMsgBytes() { - return ByteString.copyFromUtf8(respMsg_); - } - - /** - * string respMsg = 2; - */ - public Builder setRespMsg(String value) { - Objects.requireNonNull(value,"RespMsg can not be null"); - - 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) { - Objects.requireNonNull(value,"RespMsgBytes can not be null"); - checkByteStringIsUtf8(value); - - respMsg_ = value.toStringUtf8(); - onChanged(); - return this; - } - - private String respTime_ = ""; - - /** - * string respTime = 3; - */ - public String getRespTime() { - return respTime_; - } - - /** - * string respTime = 3; - */ - public com.google.protobuf.ByteString getRespTimeBytes() { - return ByteString.copyFromUtf8(respTime_); - } - - /** - * string respTime = 3; - */ - public Builder setRespTime( - String value) { - Objects.requireNonNull(value,"RespTime can not be null"); - - 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) { - Objects.requireNonNull(value,"RespTimeBytes can not be null"); - checkByteStringIsUtf8(value); - - respTime_ = value.toStringUtf8(); - 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 deleted file mode 100644 index 9ffcff9482..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/ResponseOrBuilder.java +++ /dev/null @@ -1,57 +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. - */ - -// 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 deleted file mode 100644 index 70d7518a01..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SimpleMessage.java +++ /dev/null @@ -1,1802 +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. - */ - -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: eventmesh-client.proto - -package org.apache.eventmesh.common.protocol.grpc.protos; - -import java.util.Objects; - -/** - * 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 = -6684279788270319330L; - - // 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: { - producerGroup_ = input.readStringRequireUtf8(); - break; - } - case 26: { - topic_ = input.readStringRequireUtf8(); - break; - } - case 34: { - content_ = input.readStringRequireUtf8(); - break; - } - case 42: { - ttl_ = input.readStringRequireUtf8(); - break; - } - case 50: { - uniqueId_ = input.readStringRequireUtf8(); - break; - } - case 58: { - seqNum_ = input.readStringRequireUtf8(); - break; - } - case 66: { - tag_ = input.readStringRequireUtf8(); - 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) { - Objects.requireNonNull(key, "key can not be null"); - 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) { - Objects.requireNonNull(key, "key can not be null"); - - java.util.Map map = - internalGetProperties().getMap(); - String value = map.get(key); - if (value == null) return defaultValue; - return value; - } - - /** - * map<string, string> properties = 9; - */ - - public String getPropertiesOrThrow( - String key) { - Objects.requireNonNull(key, "key can not be null"); - - 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() { - if (memoizedIsInitialized == 1) return true; - if (memoizedIsInitialized == 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; - return (hasHeader() ? other.hasHeader() && getHeader().equals(other.getHeader()) : !other.hasHeader()) - && getProducerGroup().equals(other.getProducerGroup()) - && getTopic().equals(other.getTopic()) - && getContent().equals(other.getContent()) - && getTtl().equals(other.getTtl()) - && getUniqueId().equals(other.getUniqueId()) - && getSeqNum().equals(other.getSeqNum()) - && getTag().equals(other.getTag()) - && internalGetProperties().equals(other.internalGetProperties()) - && unknownFields.equals(other.unknownFields); - } - - @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) { - return new Builder(parent); - } - - /** - * 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) { - Objects.requireNonNull(value, "RequestHeader can not be null"); - 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) { - Objects.requireNonNull(value, "ProducerGroup can not be null"); - - 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) { - Objects.requireNonNull(value, "ProducerGroupBytes can not be null"); - - 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) { - Objects.requireNonNull(value, "Topic can not be null"); - - 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) { - Objects.requireNonNull(value, "TopicBytes can not be null"); - 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) { - Objects.requireNonNull(value, "Content can not be null"); - - 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) { - Objects.requireNonNull(value, "ContentBytes can not be null"); - - 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) { - Objects.requireNonNull(value, "Ttl can not be null"); - - 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) { - Objects.requireNonNull(value, "TtlBytes can not be null"); - - 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) { - Objects.requireNonNull(value, "UniqueId can not be null"); - - 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) { - Objects.requireNonNull(value, "UniqueIdBytes can not be null"); - - 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) { - Objects.requireNonNull(value, "SeqNum can not be null"); - - 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) { - Objects.requireNonNull(value, "SeqNumBytes can not be null"); - 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) { - Objects.requireNonNull(value, "tag can not be null"); - - 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) { - Objects.requireNonNull(value, "TagBytes can not be null"); - 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) { - Objects.requireNonNull(key, "key can not be null"); - - 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) { - Objects.requireNonNull(key, "key can not be null"); - - java.util.Map map = - internalGetProperties().getMap(); - String value = map.get(key); - if (value == null) return defaultValue; - return value; - } - - /** - * map<string, string> properties = 9; - */ - - public String getPropertiesOrThrow(String key) { - Objects.requireNonNull(key, "key can not be null"); - - 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) { - Objects.requireNonNull(key, "key can not be null"); - - 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; - } - -} \ No newline at end of file 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 deleted file mode 100644 index dfda9c63ae..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SimpleMessageOrBuilder.java +++ /dev/null @@ -1,144 +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. - */ - -// 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 deleted file mode 100644 index 7b33ff72b4..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/Subscription.java +++ /dev/null @@ -1,3932 +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. - */ - -// 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_; - return result && unknownFields.equals(other.unknownFields); - } - - @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) { - return new Builder(parent); - } - /** - * 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(); - String value = map.get(key); - if(value == null) return defaultValue; - return value; - } - /** - * 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()); - return result && unknownFields.equals(other.unknownFields); - } - - @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) { - return new Builder(parent); - } - /** - * 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(); - String value = map.get(key); - if(value == null) return defaultValue; - return value; - } - /** - * 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 (Subscription.SubscriptionItem item : subscriptionItems_) { - output.writeMessage(3, item); - } - 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 (Subscription.SubscriptionItem item : subscriptionItems_) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(3, item); - } - 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()); - } - return result && unknownFields.equals(other.unknownFields); - } - - @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) { - return new Builder(parent); - } - /** - * 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 deleted file mode 100644 index 4adff7d4fc..0000000000 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/grpc/protos/SubscriptionOrBuilder.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. - */ - -// 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 index 76cda7a70f..96c75af90f 100644 --- 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 @@ -22,12 +22,11 @@ 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.common.RequestCode; 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.Objects; import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; @@ -61,10 +60,10 @@ public class HttpCommand implements ProtocolTransportObject { private transient Body body; - //Command request time + // Command request time public long reqTime; - //Command response time + // Command response time public long resTime; public CmdType cmdType = CmdType.REQ; @@ -82,8 +81,8 @@ public HttpCommand(String httpMethod, String httpVersion, String requestCode) { } public HttpCommand createHttpCommandResponse(Header header, Body body) { - if (StringUtils.isBlank(requestCode)) { - return null; + if (this.requestCode == null) { + this.requestCode = RequestCode.UNKNOWN.getRequestCode().toString(); } HttpCommand response = new HttpCommand(this.httpMethod, this.httpVersion, this.requestCode); response.setOpaque(this.opaque); @@ -96,8 +95,8 @@ public HttpCommand createHttpCommandResponse(Header header, Body body) { } public HttpCommand createHttpCommandResponse(EventMeshRetCode eventMeshRetCode) { - if (StringUtils.isBlank(requestCode)) { - return null; + if (this.requestCode == null) { + this.requestCode = RequestCode.UNKNOWN.getRequestCode().toString(); } HttpCommand response = new HttpCommand(this.httpMethod, this.httpVersion, this.requestCode); response.setOpaque(this.opaque); @@ -176,6 +175,20 @@ public DefaultFullHttpResponse httpResponse() throws Exception { return response; } + public DefaultFullHttpResponse httpResponse(HttpResponseStatus httpResponseStatus) throws Exception { + if (cmdType == CmdType.REQ) { + return null; + } + DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, httpResponseStatus, + Unpooled.wrappedBuffer(Objects.requireNonNull(JsonUtils.toJSONString(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 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 index 2779bb73d8..a19539f477 100644 --- 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 @@ -22,13 +22,12 @@ 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.util.EnumSet; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -43,28 +42,29 @@ import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; - public class HttpEventWrapper implements ProtocolTransportObject { public static final long serialVersionUID = -8547334421415366981L; - private Map headerMap = new HashMap<>(); + private transient Map headerMap = new HashMap<>(); - private Map sysHeaderMap = new HashMap<>(); + private transient Map sysHeaderMap = new HashMap<>(); private byte[] body; private String requestURI; - public String httpMethod; + private String httpMethod; + + private String httpVersion; - public String httpVersion; + // Command request time + private long reqTime; - //Command request time - public long reqTime; + // Command response time + private long resTime; - //Command response time - public long resTime; + private HttpResponseStatus httpResponseStatus = HttpResponseStatus.OK; public HttpEventWrapper() { this(null, null, null); @@ -180,7 +180,7 @@ public void setBody(byte[] newBody) { } public DefaultFullHttpResponse httpResponse() throws Exception { - DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, + DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, httpResponseStatus, Unpooled.wrappedBuffer(this.body)); HttpHeaders headers = response.headers(); headers.add(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=" + Constants.DEFAULT_CHARSET); @@ -192,19 +192,19 @@ public DefaultFullHttpResponse httpResponse() throws Exception { 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"); + EnumSet clientInstanceKeys = EnumSet.allOf(ProtocolKey.ClientInstanceKey.class); + for (ProtocolKey.ClientInstanceKey clientInstanceKey : clientInstanceKeys) { + switch (clientInstanceKey) { + case BIZSEQNO: + case UNIQUEID: + break; + default: + sysHeaderMap.put(clientInstanceKey.getKey(), + headerMap.getOrDefault(clientInstanceKey.getKey(), clientInstanceKey.getValue())); + } + } } public void buildSysHeaderForCE() { @@ -225,4 +225,8 @@ public void buildSysHeaderForCE() { sysHeaderMap.put(ProtocolKey.CloudEventsKey.SUBJECT, topic); } + public void setHttpResponseStatus(HttpResponseStatus httpResponseStatus) { + this.httpResponseStatus = httpResponseStatus; + } + } \ 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 index f773c37fa1..9b490f978d 100644 --- 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 @@ -22,7 +22,6 @@ import lombok.Builder; import lombok.Data; - @Data @Builder public class WebhookProtocolTransportObject implements ProtocolTransportObject { 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 index aefa711840..570e2af481 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.common.protocol.http.body; - import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; import java.util.HashMap; 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 index 3dc8e6c272..2bb0775439 100644 --- 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 @@ -17,7 +17,6 @@ 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; @@ -37,35 +36,38 @@ 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); + RequestCode code = RequestCode.get(Integer.valueOf(requestCode)); + if (code == null) { + throw new Exception("Request code " + requestCode + "not support"); } - 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(); + switch (code) { + case MSG_BATCH_SEND: + return SendMessageBatchRequestBody.buildBody(originalMap); + case MSG_BATCH_SEND_V2: + return SendMessageBatchV2RequestBody.buildBody(originalMap); + case MSG_SEND_ASYNC: + case MSG_SEND_SYNC: + return SendMessageRequestBody.buildBody(originalMap); + case HTTP_PUSH_CLIENT_ASYNC: + case HTTP_PUSH_CLIENT_SYNC: + return PushMessageRequestBody.buildBody(originalMap); + case REGISTER: + return RegRequestBody.buildBody(originalMap); + case UNREGISTER: + return UnRegRequestBody.buildBody(originalMap); + case SUBSCRIBE: + return SubscribeRequestBody.buildBody(originalMap); + case UNSUBSCRIBE: + return UnSubscribeRequestBody.buildBody(originalMap); + case HEARTBEAT: + return HeartbeatRequestBody.buildBody(originalMap); + case REPLY_MESSAGE: + return ReplyMessageRequestBody.buildBody(originalMap); + case ADMIN_SHUTDOWN: + return BaseRequestBody.buildBody(originalMap); + default: + throw new Exception("Request code " + requestCode + "not support"); } + } } 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 index ea6b1c3494..aef3177823 100644 --- 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 @@ -66,12 +66,16 @@ public Map toMap() { return map; } - @ToString + @Data public static class HeartbeatEntity { - public String topic; - public String serviceId; - public String url; - public String instanceId; + private String topic; + private String serviceId; + private String url; + private String instanceId; + + } + + } 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 index 6bc5aeec4a..5112b7cd4b 100644 --- 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 @@ -28,13 +28,13 @@ public class HeartbeatResponseBody extends Body { - //return code + // return code private Integer retCode; - //response message + // response message private String retMsg; - //response time + // response time private long resTime = System.currentTimeMillis(); public Integer getRetCode() { 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 index a69a8f3a31..595d7b5b19 100644 --- 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 @@ -25,13 +25,13 @@ public class ReplyMessageResponseBody extends Body { - //return code + // return code private Integer retCode; - //response message + // response message private String retMsg; - //response time + // response time private long resTime = System.currentTimeMillis(); public Integer getRetCode() { 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 index 210cc06346..4987e298e6 100644 --- 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 @@ -115,8 +115,9 @@ public static SendMessageBatchRequestBody buildBody(final Map bo String batchId = MapUtils.getString(bodyParam, BATCHID); String size = StringUtils.isBlank(MapUtils.getString(bodyParam, - SIZE)) ? "1" : MapUtils.getString(bodyParam, - SIZE); + SIZE)) ? "1" + : MapUtils.getString(bodyParam, + SIZE); String contents = MapUtils.getString(bodyParam, CONTENTS, null); SendMessageBatchRequestBody body = new SendMessageBatchRequestBody(); 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 index d248a1bd8e..90b2316e34 100644 --- 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 @@ -25,13 +25,13 @@ public class SendMessageBatchResponseBody extends Body { - //return code + // return code private Integer retCode; - //response message + // response message private String retMsg; - //response time + // response time private long resTime = System.currentTimeMillis(); public Integer getRetCode() { 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 index 479f56ce93..cd4507e9ed 100644 --- 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 @@ -25,13 +25,13 @@ public class SendMessageBatchV2ResponseBody extends Body { - //return code + // return code private Integer retCode; - //response message + // response message private String retMsg; - //response time + // response time private long resTime = System.currentTimeMillis(); public Integer getRetCode() { 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 index bc551a2b46..5f21778628 100644 --- 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 @@ -20,28 +20,31 @@ 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, "), + 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 error"), + EVENTMESH_WAITING_RR_MSG_ERR(4, "eventMesh waiting rr msg error"), + EVENTMESH_PROTOCOL_HEADER_ERR(6, "eventMesh protocol[header] error"), + EVENTMESH_PROTOCOL_BODY_ERR(7, "eventMesh protocol[body] error"), + 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_GROUP_PRODUCER_STOPED_ERR(14, "eventMesh group producer stopped"), + EVENTMESH_SEND_ASYNC_MSG_ERR(15, "eventMesh send async msg error"), 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, "); + EVENTMESH_SEND_BATCHLOG_MSG_ERR(17, "eventMesh send batch log msg error"), + EVENTMESH_RUNTIME_ERR(18, "eventMesh runtime error"), + EVENTMESH_SUBSCRIBE_ERR(19, "eventMesh subscribe error"), + EVENTMESH_UNSUBSCRIBE_ERR(20, "eventMesh unsubscribe error"), + EVENTMESH_HEARTBEAT_ERR(21, "eventMesh heartbeat error"), + EVENTMESH_ACL_ERR(22, "eventMesh acl error"), + EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR(23, "eventMesh http msg send over the limit"), + + EVENTMESH_FILTER_MSG_ERR(24, "eventMesh filter async msg error"), + EVENTMESH_OPERATE_FAIL(100, "operate fail"); private final Integer retCode; 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 index 3125680c14..71ad6eef09 100644 --- 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 @@ -17,6 +17,9 @@ package org.apache.eventmesh.common.protocol.http.common; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + public class ProtocolKey { public static final String REQUEST_CODE = "code"; @@ -29,31 +32,48 @@ public class ProtocolKey { public static final String PROTOCOL_VERSION = "protocolversion"; public static final String PROTOCOL_DESC = "protocoldesc"; + public static final String TOPIC = "topic"; 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 final String TOKEN = "token"; - } + public enum ClientInstanceKey { + + //////////////////////////////////// Protocol layer requester description/////////// + ENV("env", "env"), + IDC("idc", "idc"), + SYS("sys", "1234"), + PID("pid", ThreadUtils.getPID()), + IP("ip", IPUtils.getLocalAddress()), + USERNAME("username", "eventmesh"), + PASSWD("passwd", "pass"), + BIZSEQNO("bizseqno", "bizseqno"), + UNIQUEID("uniqueid", "uniqueid"), + PRODUCERGROUP("producergroup", "em-http-producer"), + CONSUMERGROUP("consumergroup", "em-http-consumer"), + + TOKEN("token", "token"); + + private final String key; + private final Object value; + + public String getKey() { + return key; + } + + public Object getValue() { + return value; + } + + ClientInstanceKey(String key, Object value) { + this.key = key; + this.value = value; + } + } public static class EventMeshInstanceKey { - ///////////////////////////////////////////////Protocol layer EventMesh description + /////////////////////////////////////////////// Protocol layer EventMesh description public static final String EVENTMESHCLUSTER = "eventmeshcluster"; public static final String EVENTMESHIP = "eventmeship"; public static final String EVENTMESHENV = "eventmeshenv"; @@ -68,8 +88,7 @@ public static class CloudEventsKey { public static final String TYPE = "type"; } - - //return of CLIENT <-> EventMesh + // 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/RequestCode.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/protocol/http/common/RequestCode.java index 1d6e351bb7..7c89f38faf 100644 --- 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 @@ -19,6 +19,8 @@ public enum RequestCode { + UNKNOWN(0, "UNKNOWN"), + MSG_BATCH_SEND(102, "SEND BATCH MSG"), MSG_BATCH_SEND_V2(107, "SEND BATCH MSG V2"), 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 index da5ebf58b3..d15def4646 100644 --- 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 @@ -29,10 +29,15 @@ public enum RequestURI { SUBSCRIBE_REMOTE("/eventmesh/subscribe/remote", "SUBSCRIBE REMOTE"), - UNSUBSCRIBE_LOCAL("/eventmesh/unsubscribe/local", "SUBSCRIBE LOCAL"), + UNSUBSCRIBE_LOCAL("/eventmesh/unsubscribe/local", "UNSUBSCRIBE LOCAL"), - UNSUBSCRIBE_REMOTE("/eventmesh/unsubscribe/remote", "SUBSCRIBE REMOTE"); + UNSUBSCRIBE_REMOTE("/eventmesh/unsubscribe/remote", "UNSUBSCRIBE REMOTE"), + CREATE_TOPIC("/eventmesh/topic/create", "CREATE TOPIC"), + + DELETE_TOPIC("/eventmesh/topic/delete", "DELETE TOPIC"), + + SUBSCRIPTION_QUERY("/eventmesh/subscrition/query", "SUBSCRIPTION QUERY"); private final String requestURI; 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 index 2a2e2c7665..f25e0a3c80 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.common.protocol.http.header; - import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; import java.util.HashMap; 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 index 9a432202a1..453b4bd35d 100644 --- 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 @@ -17,7 +17,6 @@ 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; 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 index 8dc6ec88a6..33062fd4c0 100644 --- 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 @@ -17,178 +17,64 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class HeartbeatRequestHeader extends Header { - //request code + // request code private String code; - //requester language description + // requester language description private String language; - //protocol version adopted by requester, default:1.0 + // protocol version adopted by requester, default:1.0 private ProtocolVersion version; - //the environment number of the requester + // the environment number of the requester private String env; - //the IDC of the requester + // the IDC of the requester private String idc; - //subsystem of the requester + // subsystem of the requester private String sys; - //PID of the requester + // PID of the requester private String pid; - //IP of the requester + // IP of the requester private String ip; - //private String producerGroup; + // private String producerGroup; - //USERNAME of the requester + // USERNAME of the requester private String username = "username"; - //PASSWD of the requester + // 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(); + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey); } public static HeartbeatRequestHeader buildHeader(Map headerParam) { + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); 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; + return (HeartbeatRequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam); } } 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 index 5c0912f722..b4158a6968 100644 --- 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 @@ -17,13 +17,19 @@ 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.apache.eventmesh.common.utils.HttpConvertsUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class HeartbeatResponseHeader extends Header { private int code; @@ -36,46 +42,6 @@ public class HeartbeatResponseHeader extends Header { 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) { @@ -88,26 +54,11 @@ public static HeartbeatResponseHeader buildHeader(Integer requestCode, String ev 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index 7cbd22ac6e..a082ce8c95 100644 --- 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 @@ -17,17 +17,20 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class RegRequestHeader extends Header { private String code; @@ -51,132 +54,15 @@ public class RegRequestHeader extends Header { private String passwd; public static RegRequestHeader buildHeader(Map headerParam) { + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); 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; + return (RegRequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam); } @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(); + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey); } } 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 index 5e3fc7fc8e..06f97099b3 100644 --- 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 @@ -17,70 +17,36 @@ 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.apache.eventmesh.common.utils.HttpConvertsUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class RegResponseHeader extends Header { - //response code, as same as the request code + // response code, as same as the request code private int code; - //The cluster name of the EventMesh that processes the request + // The cluster name of the EventMesh that processes the request private String eventMeshCluster; - //IP of the EventMesh that processes the request + // IP of the EventMesh that processes the request private String eventMeshIp; - //Environment number of the EventMesh that processes the request + // Environment number of the EventMesh that processes the request private String eventMeshEnv; - //IDC of the EventMesh that processes the request + // 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(); @@ -92,27 +58,12 @@ public static RegResponseHeader buildHeader(Integer requestCode, String eventMes 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index 2eb83e2931..82dc2ce167 100644 --- 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 @@ -17,17 +17,20 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class SubscribeRequestHeader extends Header { private String code; @@ -51,132 +54,16 @@ public class SubscribeRequestHeader extends Header { private String passwd; public static SubscribeRequestHeader buildHeader(Map headerParam) { + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); 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; + return (SubscribeRequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam); } @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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey); } - @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 index 99c8ce92c5..f50d37743e 100644 --- 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 @@ -19,10 +19,17 @@ import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; import org.apache.eventmesh.common.protocol.http.header.Header; +import org.apache.eventmesh.common.utils.HttpConvertsUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class SubscribeResponseHeader extends Header { private int code; @@ -35,46 +42,6 @@ public class SubscribeResponseHeader extends Header { 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) { @@ -87,27 +54,12 @@ public static SubscribeResponseHeader buildHeader(Integer requestCode, String ev 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index 94af59908f..7ca214c508 100644 --- 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 @@ -17,177 +17,63 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class UnRegRequestHeader extends Header { - //request code + // request code private String code; - //requester language description + // requester language description private String language; - //protocol version adopted by requester, default:1.0 + // protocol version adopted by requester, default:1.0 private ProtocolVersion version; - //the environment number of the requester + // the environment number of the requester private String env; - //the IDC of the requester + // the IDC of the requester private String idc; - //subsystem of the requester + // subsystem of the requester private String sys; - //PID of the requester + // PID of the requester private String pid; - //IP of the requester + // IP of the requester private String ip; - //USERNAME of the requester + // USERNAME of the requester private String username = "username"; - //PASSWD of the requester + // PASSWD of the requester private String passwd = "user@123"; public static UnRegRequestHeader buildHeader(Map headerParam) { + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); 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; + return (UnRegRequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam); } @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(); + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey); } } 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 index 0bbf67f076..25bfc78e17 100644 --- 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 @@ -17,13 +17,19 @@ 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.apache.eventmesh.common.utils.HttpConvertsUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class UnRegResponseHeader extends Header { private int code; @@ -36,46 +42,6 @@ public class UnRegResponseHeader extends Header { 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(); @@ -87,27 +53,12 @@ public static UnRegResponseHeader buildHeader(Integer requestCode, String eventM 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index 8d4eb7c7cf..b0390ec625 100644 --- 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 @@ -17,17 +17,20 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class UnSubscribeRequestHeader extends Header { private String code; @@ -51,132 +54,16 @@ public class UnSubscribeRequestHeader extends Header { private String passwd; public static UnSubscribeRequestHeader buildHeader(Map headerParam) { + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); 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; + return (UnSubscribeRequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam); } @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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey); } - @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 index f3cafb2650..276cee6390 100644 --- 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 @@ -19,10 +19,17 @@ import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; import org.apache.eventmesh.common.protocol.http.header.Header; +import org.apache.eventmesh.common.utils.HttpConvertsUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class UnSubscribeResponseHeader extends Header { private int code; @@ -35,46 +42,6 @@ public class UnSubscribeResponseHeader extends Header { 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(); @@ -86,26 +53,11 @@ public static UnSubscribeResponseHeader buildHeader(Integer requestCode, String 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index 38ff905943..e22c3bf050 100644 --- 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 @@ -17,26 +17,29 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class PushMessageRequestHeader extends Header { - //request code + // request code private int code; - //requester language description + // requester language description private String language; - //protocol version adopted by requester, default:1.0 + // protocol version adopted by requester, default:1.0 private ProtocolVersion version; private String eventMeshCluster; @@ -47,99 +50,19 @@ public class PushMessageRequestHeader extends Header { 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + PushMessageRequestHeader header = new PushMessageRequestHeader(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return (PushMessageRequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam, eventMeshInstanceKey); } @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(); + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index f0e05bc3b8..6ba742cd18 100644 --- 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 @@ -17,127 +17,53 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class PushMessageResponseHeader extends Header { - //response code + // response code private int code; - //requester language description + // requester language description private String language; - //protocol version adopted by requester, default:1.0 + // protocol version adopted by requester, default:1.0 private ProtocolVersion version; - //the environment number of the requester + // the environment number of the requester private String env; - //the IDC of the requester + // the IDC of the requester private String idc; - //subsystem of the requester + // subsystem of the requester private String sys; - //PID of the requester + // PID of the requester private String pid; - //IP of the requester + // IP of the requester private String ip; - //USERNAME of the requester + // USERNAME of the requester private String username; - //PASSWD of the requester + // 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(); @@ -152,36 +78,10 @@ public static PushMessageResponseHeader buildHeader(int requestCode, String clie 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey); } } 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 index e56a79d9e0..94300c67a1 100644 --- 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 @@ -17,213 +17,71 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class ReplyMessageRequestHeader extends Header { - //request code + // request code private String code; - //requester language description + // requester language description private String language; - //protocol version adopted by requester, default:1.0 + // protocol version adopted by requester, default:1.0 private ProtocolVersion version; - //protocol type, cloudevents or eventmeshMessage + // protocol type, cloudevents or eventmeshMessage private String protocolType; - //protocol version, cloudevents:1.0 or 0.3 + // protocol version, cloudevents:1.0 or 0.3 private String protocolVersion; - //protocol desc + // protocol desc private String protocolDesc; - //the environment number of the requester + // the environment number of the requester private String env; - //the IDC of the requester + // the IDC of the requester private String idc; - //subsystem of the requester + // subsystem of the requester private String sys; - //PID of the requester + // PID of the requester private String pid; - //IP of the requester + // IP of the requester private String ip; - //USERNAME of the requester + // USERNAME of the requester private String username; - //PASSWD of the requester + // 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) { + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); 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; + return (ReplyMessageRequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam); } @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(); + ProtocolKey protocolKey = new ProtocolKey(); + return new HttpConvertsUtils().httpMapConverts(this, protocolKey); } } 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 index 64811e4596..05a20018a1 100644 --- 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 @@ -17,70 +17,36 @@ 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 org.apache.eventmesh.common.utils.HttpConvertsUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class ReplyMessageResponseHeader extends Header { - //response code, as same as the request code + // response code, as same as the request code private int code; - //The cluster name of the EventMesh that processes the request + // The cluster name of the EventMesh that processes the request private String eventMeshCluster; - //IP of the EventMesh that processes the request + // IP of the EventMesh that processes the request private String eventMeshIp; - //Environment number of the EventMesh that processes the request + // Environment number of the EventMesh that processes the request private String eventMeshEnv; - //IDC of the EventMesh that processes the request + // 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) { @@ -93,26 +59,11 @@ public static ReplyMessageResponseHeader buildHeader(Integer requestCode, String 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index f3e9557fa3..297cc70d66 100644 --- 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 @@ -17,214 +17,72 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class SendMessageBatchRequestHeader extends Header { - //request code + // request code private String code; - //requester language description + // requester language description private String language; - //protocol version adopted by requester, default:1.0 + // protocol version adopted by requester, default:1.0 private ProtocolVersion version; - //protocol type, cloudevents or eventmeshMessage + // protocol type, cloudevents or eventmeshMessage private String protocolType; - //protocol version, cloudevents:1.0 or 0.3 + // protocol version, cloudevents:1.0 or 0.3 private String protocolVersion; - //protocol desc + // protocol desc private String protocolDesc; - //the environment number of the requester + // the environment number of the requester private String env; - //the IDC of the requester + // the IDC of the requester private String idc; - //subsystem of the requester + // subsystem of the requester private String sys; - //PID of the requester + // PID of the requester private String pid; - //IP of the requester + // IP of the requester private String ip; - //USERNAME of the requester + // USERNAME of the requester private String username; - //PASSWD of the requester + // 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) { + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); 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; + return (SendMessageBatchRequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam); } @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(); + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey); } } 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 index 9a0ea6d580..7d9f8c6cd2 100644 --- 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 @@ -17,70 +17,36 @@ 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 org.apache.eventmesh.common.utils.HttpConvertsUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class SendMessageBatchResponseHeader extends Header { - //response code, as same as the request code + // response code, as same as the request code private int code; - //The cluster name of the EventMesh that processes the request + // The cluster name of the EventMesh that processes the request private String eventMeshCluster; - //IP of the EventMesh that processes the request + // IP of the EventMesh that processes the request private String eventMeshIp; - //Environment number of the EventMesh that processes the request + // Environment number of the EventMesh that processes the request private String eventMeshEnv; - //IDC of the EventMesh that processes the request + // 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) { @@ -93,26 +59,11 @@ public static SendMessageBatchResponseHeader buildHeader(Integer requestCode, St 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index 186f3d153a..25c42ac2d3 100644 --- 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 @@ -17,213 +17,71 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class SendMessageBatchV2RequestHeader extends Header { - //request code + // request code private String code; - //requester language description + // requester language description private String language; - //protocol version adopted by requester, default:1.0 + // protocol version adopted by requester, default:1.0 private ProtocolVersion version; - //protocol type, cloudevents or eventmeshMessage + // protocol type, cloudevents or eventmeshMessage private String protocolType; - //protocol version, cloudevents:1.0 or 0.3 + // protocol version, cloudevents:1.0 or 0.3 private String protocolVersion; - //protocol desc + // protocol desc private String protocolDesc; - //the environment number of the requester + // the environment number of the requester private String env; - //the IDC of the requester + // the IDC of the requester private String idc; - //subsystem of the requester + // subsystem of the requester private String sys; - //PID of the requester + // PID of the requester private String pid; - //IP of the requester + // IP of the requester private String ip; - //USERNAME of the requester + // USERNAME of the requester private String username; - //PASSWD of the requester + // 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) { + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); 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; + return (SendMessageBatchV2RequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam); } @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(); + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey); } } 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 index dadb18a0a5..1afe670be0 100644 --- 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 @@ -19,68 +19,35 @@ import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; import org.apache.eventmesh.common.protocol.http.header.Header; +import org.apache.eventmesh.common.utils.HttpConvertsUtils; import org.apache.eventmesh.common.utils.IPUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class SendMessageBatchV2ResponseHeader extends Header { - //response code, as same as the request code + // response code, as same as the request code private int code; - //The cluster name of the EventMesh that processes the request + // The cluster name of the EventMesh that processes the request private String eventMeshCluster; - //IP of the EventMesh that processes the request + // IP of the EventMesh that processes the request private String eventMeshIp; - //Environment number of the EventMesh that processes the request + // Environment number of the EventMesh that processes the request private String eventMeshEnv; - //IDC of the EventMesh that processes the request + // 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 eventMeshEnv, String eventMeshIDC) { SendMessageBatchV2ResponseHeader header = new SendMessageBatchV2ResponseHeader(); @@ -92,26 +59,11 @@ public static SendMessageBatchV2ResponseHeader buildHeader(Integer requestCode, 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index df9c3670dd..c2aa5709a8 100644 --- 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 @@ -17,214 +17,72 @@ 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.eventmesh.common.utils.HttpConvertsUtils; -import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; - -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class SendMessageRequestHeader extends Header { - //request code + // request code private String code; - //requester language description + // requester language description private String language; - //protocol version adopted by requester, default:1.0 + // protocol version adopted by requester, default:1.0 private ProtocolVersion version; - //protocol type, cloudevents or eventmeshMessage + // protocol type, cloudevents or eventmeshMessage private String protocolType; - //protocol version, cloudevents:1.0 or 0.3 + // protocol version, cloudevents:1.0 or 0.3 private String protocolVersion; - //protocol desc + // protocol desc private String protocolDesc; - //the environment number of the requester + // the environment number of the requester private String env; - //the IDC of the requester + // the IDC of the requester private String idc; - //subsystem of the requester + // subsystem of the requester private String sys; - //PID of the requester + // PID of the requester private String pid; - //IP of the requester + // IP of the requester private String ip; - //USERNAME of the requester + // USERNAME of the requester private String username; - //PASSWD of the requester + // 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) { + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); 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; + return (SendMessageRequestHeader) httpConvertsUtils.httpHeaderConverts(header, headerParam); } @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(); + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey); } } 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 index b4b9883814..70d391f614 100644 --- 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 @@ -17,70 +17,36 @@ 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 org.apache.eventmesh.common.utils.HttpConvertsUtils; -import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Setter +@Getter +@ToString public class SendMessageResponseHeader extends Header { - //response code, as same as the request code + // response code, as same as the request code private int code; - //The cluster name of the EventMesh that processes the request + // The cluster name of the EventMesh that processes the request private String eventMeshCluster; - //IP of the EventMesh that processes the request + // IP of the EventMesh that processes the request private String eventMeshIp; - //Environment number of the EventMesh that processes the request + // Environment number of the EventMesh that processes the request private String eventMeshEnv; - //IDC of the EventMesh that processes the request + // 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) { @@ -93,26 +59,11 @@ public static SendMessageResponseHeader buildHeader(Integer requestCode, String 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; + HttpConvertsUtils httpConvertsUtils = new HttpConvertsUtils(); + ProtocolKey protocolKey = new ProtocolKey(); + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey = new ProtocolKey.EventMeshInstanceKey(); + return httpConvertsUtils.httpMapConverts(this, protocolKey, eventMeshInstanceKey); } } 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 index 5e980a1b46..7ab2744223 100644 --- 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 @@ -19,70 +19,70 @@ 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 + // 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; 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 index 9c9a2890bc..864cec2127 100644 --- 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 @@ -48,7 +48,6 @@ public Header(int code, String desc, String seq, Map properties) this.properties = properties; } - public void putProperty(final String name, final Object value) { if (null == this.properties) { this.properties = new HashMap<>(); 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 index 14d6f31cd6..81294cc2a2 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.common.protocol.tcp; - import org.apache.eventmesh.common.protocol.ProtocolTransportObject; public class Package implements ProtocolTransportObject { @@ -34,7 +33,6 @@ public Object getBody() { return body; } - public void setHeader(Header header) { this.header = header; } 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 index 943988f323..f1a6dbcdd1 100644 --- 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 @@ -19,12 +19,12 @@ import org.apache.eventmesh.common.protocol.SubscriptionItem; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; public class Subscription { - private List topicList = new LinkedList<>(); + private List topicList = new ArrayList<>(); public Subscription() { } 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 index e80bc2dbd0..4d17a0735a 100644 --- 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 @@ -103,7 +103,6 @@ public boolean equals(Object o) { return false; } - if (!Objects.equals(path, userAgent.path)) { return false; } 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 index 3e86ba7524..c24ef94a8e 100644 --- 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 @@ -25,18 +25,17 @@ 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.eventmesh.common.utils.LogUtil; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import java.util.Arrays; -import java.util.List; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.MessageToByteEncoder; -import io.netty.handler.codec.ReplayingDecoder; - import com.fasterxml.jackson.core.JsonProcessingException; import com.google.common.base.Preconditions; @@ -51,6 +50,10 @@ public class Codec { private static final byte[] CONSTANT_MAGIC_FLAG = serializeBytes("EventMesh"); private static final byte[] VERSION = serializeBytes("0000"); + private static final int PREFIX_LENGTH = CONSTANT_MAGIC_FLAG.length + VERSION.length; //13 + + private static final int PACKAGE_BYTES_FIELD_LENGTH = 4; + public static class Encoder extends MessageToByteEncoder { @Override @@ -58,9 +61,7 @@ public void encode(ChannelHandlerContext ctx, Package pkg, ByteBuf out) throws E 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.toJSONString(pkg)); - } + LogUtil.debug(log, "Encode pkg={}", () -> JsonUtils.toJSONString(pkg)); final byte[] headerData = JsonUtils.toJSONBytes(header); final byte[] bodyData; @@ -74,7 +75,7 @@ public void encode(ChannelHandlerContext ctx, Package pkg, ByteBuf out) throws E int headerLength = ArrayUtils.getLength(headerData); int bodyLength = ArrayUtils.getLength(bodyData); - final int length = CONSTANT_MAGIC_FLAG.length + VERSION.length + headerLength + bodyLength; + final int length = PREFIX_LENGTH + headerLength + bodyLength; if (length > FRAME_MAX_LENGTH) { throw new IllegalArgumentException("message size is exceed limit!"); @@ -101,31 +102,62 @@ public void encode(ChannelHandlerContext ctx, Package pkg, ByteBuf out) throws E } } - public static class Decoder extends ReplayingDecoder { + public static class Decoder extends LengthFieldBasedFrameDecoder { + + public Decoder() { + /** + * lengthAdjustment value = -9 explain: + * Header + Body, Format: + *
+             * ┌───────────────┬─────────────┬──────────────────┬──────────────────┬──────────────────┬─────────────────┐
+             * │   MAGIC_FLAG  │   VERSION   │ package length   │   Header length  │      Header      │      body       │
+             * │    (9bytes)   │  (4bytes)   │    (4bytes)      │      (4bytes)    │   (header bytes) │   (body bytes)  │
+             * └───────────────┴─────────────┴──────────────────┴──────────────────┴──────────────────┴─────────────────┘
+             * 
+ * package length = MAGIC_FLAG + VERSION + Header length + Body length,Currently, + * adding MAGIC_FLAG + VERSION + package length field (4 bytes) actually adds 17 bytes. + * However, the value of the package length field is only reduced by the four bytes of + * the package length field itself and the four bytes of the header length field. + * Therefore, the compensation value to be added to the length field value is -9, + * which means subtracting the extra 9 bytes. + * Refer to the encoding in the {@link Encoder} + */ + super(FRAME_MAX_LENGTH, PREFIX_LENGTH, PACKAGE_BYTES_FIELD_LENGTH, -9, 0); + } @Override - public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { + + ByteBuf target = null; + try { - if (null == in) { - return; + target = (ByteBuf) super.decode(ctx, in); + if (null == target) { + return null; } - - byte[] flagBytes = parseFlag(in); - byte[] versionBytes = parseVersion(in); + byte[] flagBytes = parseFlag(target); + byte[] versionBytes = parseVersion(target); validateFlag(flagBytes, versionBytes, ctx); - final int length = in.readInt(); - final int headerLength = in.readInt(); - final int bodyLength = length - CONSTANT_MAGIC_FLAG.length - VERSION.length - headerLength; - Header header = parseHeader(in, headerLength); - Object body = parseBody(in, header, bodyLength); + final int length = target.readInt(); + final int headerLength = target.readInt(); + final int bodyLength = length - PREFIX_LENGTH - headerLength; + Header header = parseHeader(target, headerLength); + Object body = parseBody(target, header, bodyLength); Package pkg = new Package(header, body); - out.add(pkg); - } catch (Exception e) { - log.error("decode error| received data: {}.", deserializeBytes(in.array()), e); - throw e; + return pkg; + + } catch (Exception ex) { + log.error("decode error", ex); + ctx.channel().close(); + } finally { + if (target != null) { + target.release(); + } } + + return null; } private byte[] parseFlag(ByteBuf in) { @@ -146,9 +178,7 @@ private Header parseHeader(ByteBuf in, int headerLength) throws JsonProcessingEx } final byte[] headerData = new byte[headerLength]; in.readBytes(headerData); - if (log.isDebugEnabled()) { - log.debug("Decode headerJson={}", deserializeBytes(headerData)); - } + LogUtil.debug(log, "Decode headerJson={}", () -> deserializeBytes(headerData)); return JsonUtils.parseObject(headerData, Header.class); } @@ -158,9 +188,7 @@ private Object parseBody(ByteBuf in, Header header, int bodyLength) throws JsonP } final byte[] bodyData = new byte[bodyLength]; in.readBytes(bodyData); - if (log.isDebugEnabled()) { - log.debug("Decode bodyJson={}", deserializeBytes(bodyData)); - } + LogUtil.debug(log, "Decode bodyJson={}", () -> deserializeBytes(bodyData)); return deserializeBody(deserializeBytes(bodyData), header); } @@ -194,15 +222,25 @@ private static Object deserializeBody(String bodyJsonString, Header header) thro case RESPONSE_TO_CLIENT_ACK: case ASYNC_MESSAGE_TO_CLIENT_ACK: case BROADCAST_MESSAGE_TO_CLIENT_ACK: + case HELLO_RESPONSE: + case RECOMMEND_RESPONSE: + case SUBSCRIBE_RESPONSE: + case LISTEN_RESPONSE: + case UNSUBSCRIBE_RESPONSE: + case HEARTBEAT_RESPONSE: + case ASYNC_MESSAGE_TO_SERVER_ACK: + case BROADCAST_MESSAGE_TO_SERVER_ACK: + case CLIENT_GOODBYE_REQUEST: + case CLIENT_GOODBYE_RESPONSE: + case SERVER_GOODBYE_REQUEST: + case SERVER_GOODBYE_RESPONSE: // 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 JsonUtils.parseObject(bodyJsonString, RedirectInfo.class); default: - if (log.isWarnEnabled()) { - log.warn("Invalidate TCP command: {}", command); - } + log.warn("Invalidate TCP command: {}", command); return null; } } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/AssertUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/AssertUtils.java index 00476277d6..a9445ba505 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/AssertUtils.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/AssertUtils.java @@ -27,9 +27,9 @@ public final class AssertUtils { /** - * assert obj not null + * Assert obj is not null * - * @param obj obj + * @param obj Object to test * @param message error message */ public static void notNull(final Object obj, final String message) { @@ -37,26 +37,25 @@ public static void notNull(final Object obj, final String message) { } /** - * assert test is true + * Assert condition is true * - * @param test test + * @param condition boolean to test * @param message error message */ - public static void isTrue(final Boolean test, final String message) { - if (!Boolean.TRUE.equals(test)) { + public static void isTrue(final Boolean condition, final String message) { + if (!Boolean.TRUE.equals(condition)) { throw new IllegalArgumentException(message); } } /** - * assert str is not black + * Assert str is not blank * - * @param str str - * @param message message + * @param str String to test + * @param message error message */ - public static void notBlack(final String str, final String message) { + public static void notBlank(final String str, final String message) { isTrue(StringUtils.isNoneBlank(str), message); } - } 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 index a7535f70ba..8617888994 100644 --- 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 @@ -17,6 +17,10 @@ package org.apache.eventmesh.common.utils; +import static org.apache.eventmesh.common.Constants.GRPC; +import static org.apache.eventmesh.common.Constants.HTTP; +import static org.apache.eventmesh.common.Constants.TCP; + import org.apache.eventmesh.common.config.CommonConfiguration; import java.util.List; @@ -32,13 +36,8 @@ 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. * @@ -62,7 +61,6 @@ public static CommonConfiguration get(String key) { return CONFIGURATION_MAP.get(key); } - /** * Removes all of the mappings from this map. */ diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/HttpConvertsUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/HttpConvertsUtils.java new file mode 100644 index 0000000000..7ac10bb862 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/HttpConvertsUtils.java @@ -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 org.apache.eventmesh.common.utils; + +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.lang.reflect.Field; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HttpConvertsUtils { + + public Map httpMapConverts(Header header, ProtocolKey protocolKey) { + Map map = new HashMap<>(); + Class headerClass = header.getClass(); + Class protocolKeyClass = protocolKey.getClass(); + Field[] headerFields = headerClass.getDeclaredFields(); + Field[] protocolKeyFields = protocolKeyClass.getDeclaredFields(); + for (Field headerField : headerFields) { + headerField.setAccessible(true); + try { + final String headerFieldName = headerField.getName(); + final Object headerFieldValue = headerField.get(header); + for (Field protocolKeyField : protocolKeyFields) { + protocolKeyField.setAccessible(true); + final String protocolKeyValue = protocolKeyField.get(protocolKey).toString(); + // Use the attribute name to compare with the key value to achieve one-to-one correspondence and ignore case. + if (StringUtils.equalsIgnoreCase(headerFieldName, protocolKeyValue)) { + map.put(protocolKeyValue, headerFieldValue); + } + } + + EnumSet clientInstanceKeys = EnumSet.allOf(ProtocolKey.ClientInstanceKey.class); + for (ProtocolKey.ClientInstanceKey clientInstanceKey : clientInstanceKeys) { + // Use the attribute name to compare with the key value to achieve one-to-one correspondence and ignore case. + if (StringUtils.equalsIgnoreCase(headerFieldName, clientInstanceKey.getKey())) { + map.put(clientInstanceKey.getKey(), headerFieldValue); + } + } + } catch (IllegalAccessException e) { + log.error("http map conversion failed.", e); + } + } + return map; + } + + public Map httpMapConverts(Header header, ProtocolKey protocolKey, + ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey) { + Map map = new HashMap<>(); + Class headerClass = header.getClass(); + Class protocolKeyClass = protocolKey.getClass(); + Class eventMeshInstanceKeyClass = eventMeshInstanceKey.getClass(); + Field[] headerFields = headerClass.getDeclaredFields(); + Field[] protocolKeyFields = protocolKeyClass.getDeclaredFields(); + Field[] eventMeshInstanceKeyFields = eventMeshInstanceKeyClass.getDeclaredFields(); + for (Field headerField : headerFields) { + headerField.setAccessible(true); + try { + final String headerFieldName = headerField.getName(); + final Object headerFieldValue = headerField.get(header); + for (Field protocolKeyField : protocolKeyFields) { + protocolKeyField.setAccessible(true); + final String protocolKeyFieldValue = protocolKeyField.get(protocolKey).toString(); + // Use the attribute name to compare with the key value to achieve one-to-one correspondence and ignore case. + if (StringUtils.equalsIgnoreCase(headerFieldName, protocolKeyFieldValue)) { + map.put(protocolKeyFieldValue, headerFieldValue); + } + } + + for (Field eventMeshInstanceKeyField : eventMeshInstanceKeyFields) { + eventMeshInstanceKeyField.setAccessible(true); + final String eventMeshInstanceKeyValue = eventMeshInstanceKeyField.get(eventMeshInstanceKey).toString(); + // Use the attribute name to compare with the key value to achieve one-to-one correspondence and ignore case. + if (StringUtils.equalsIgnoreCase(headerFieldName, eventMeshInstanceKeyValue)) { + map.put(eventMeshInstanceKeyValue, headerFieldValue); + } + } + } catch (IllegalAccessException e) { + log.error("http map conversion failed.", e); + } + } + return map; + } + + public Header httpHeaderConverts(Header header, Map headerParam) { + Class headerClass = header.getClass(); + ProtocolKey protocolKey = new ProtocolKey(); + Class protocolKeyClass = protocolKey.getClass(); + Field[] protocolKeyFields = protocolKeyClass.getDeclaredFields(); + Field[] headerFields = headerClass.getDeclaredFields(); + + for (Field headerField : headerFields) { + headerField.setAccessible(true); + String headerFieldName = headerField.getName(); + try { + setFiledValue(header, headerParam, protocolKey, protocolKeyFields, headerField, headerFieldName); + + EnumSet clientInstanceKeys = EnumSet.allOf(ProtocolKey.ClientInstanceKey.class); + for (ProtocolKey.ClientInstanceKey clientInstanceKey : clientInstanceKeys) { + // Use the attribute name to compare with the key value to achieve one-to-one correspondence and ignore case. + if (StringUtils.equalsIgnoreCase(headerFieldName, clientInstanceKey.getKey())) { + headerField.set(header, MapUtils.getString(headerParam, clientInstanceKey.getKey())); + } + } + } catch (IllegalAccessException e) { + log.error("http header builder conversion failed.", e); + } + } + return header; + } + + public Header httpHeaderConverts(Header header, Map headerParam, ProtocolKey.EventMeshInstanceKey eventMeshInstanceKey) { + Class headerClass = header.getClass(); + ProtocolKey protocolKey = new ProtocolKey(); + Class protocolKeyClass = protocolKey.getClass(); + Class eventMeshInstanceKeyClass = eventMeshInstanceKey.getClass(); + Field[] protocolKeyFields = protocolKeyClass.getDeclaredFields(); + Field[] headerFields = headerClass.getDeclaredFields(); + Field[] eventMeshInstanceKeyFields = eventMeshInstanceKeyClass.getDeclaredFields(); + for (Field headerField : headerFields) { + headerField.setAccessible(true); + String headerFieldName = headerField.getName(); + try { + setFiledValue(header, headerParam, protocolKey, protocolKeyFields, headerField, headerFieldName); + + for (Field eventMeshInstanceKeyField : eventMeshInstanceKeyFields) { + eventMeshInstanceKeyField.setAccessible(true); + final String eventMeshInstanceKeyValue = eventMeshInstanceKeyField.get(eventMeshInstanceKey).toString(); + // Use the attribute name to compare with the key value to achieve one-to-one correspondence and ignore case. + if (StringUtils.equalsIgnoreCase(headerFieldName, eventMeshInstanceKeyValue)) { + headerField.set(header, MapUtils.getString(headerParam, eventMeshInstanceKeyValue)); + } + } + + } catch (IllegalAccessException e) { + log.error("http header builder conversion failed.", e); + } + } + return header; + } + + private void setFiledValue(Header header, Map headerParam, ProtocolKey protocolKey, + Field[] protocolKeyFields, Field headerField, + String headerFieldName) throws IllegalAccessException { + for (Field protocolKeyField : protocolKeyFields) { + protocolKeyField.setAccessible(true); + switch (headerFieldName) { + case ProtocolKey.VERSION: + ProtocolVersion protocolVersion = ProtocolVersion.get(MapUtils.getString(headerParam, ProtocolKey.VERSION)); + if (Objects.nonNull(protocolVersion)) { + headerField.set(header, protocolVersion); + } + break; + case ProtocolKey.LANGUAGE: + String language = StringUtils.isBlank(MapUtils.getString(headerParam, ProtocolKey.LANGUAGE)) + ? Constants.LANGUAGE_JAVA + : MapUtils.getString(headerParam, ProtocolKey.LANGUAGE); + headerField.set(header, language); + break; + default: + String protocolKeyValue = protocolKeyField.get(protocolKey).toString(); + // Use the attribute name to compare with the key value to achieve one-to-one correspondence and ignore case. + if (StringUtils.equalsIgnoreCase(headerFieldName, protocolKeyValue)) { + Object value = getValue(headerParam, protocolKeyValue); + if (Objects.nonNull(value)) { + headerField.set(header, value); + } + } + break; + } + } + } + + /** + * map.get(key) gets the value and determines the data type for the corresponding operation. + * @param headerParam map + * @param protocolKeyValue key + * @return value + */ + private Object getValue(Map headerParam, String protocolKeyValue) { + Object mapValue = headerParam.get(protocolKeyValue); + Object value = null; + if (mapValue instanceof Integer) { + value = MapUtils.getIntValue(headerParam, protocolKeyValue); + } else if (mapValue instanceof String) { + value = MapUtils.getString(headerParam, protocolKeyValue); + } + return value; + } + +} 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 index c4e7ca46f1..f22389ffde 100644 --- 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 @@ -29,6 +29,7 @@ import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Enumeration; import java.util.List; import java.util.regex.Matcher; @@ -36,7 +37,6 @@ import io.netty.channel.Channel; - import lombok.extern.slf4j.Slf4j; import inet.ipaddr.HostName; @@ -54,19 +54,24 @@ public static String getLocalAddress() { return dockerHostIp; } - //priority of networkInterface when generating client ip + // priority of networkInterface when generating client ip String priority = System.getProperty("networkInterface.priority", "eth0 list = Arrays.asList(priority.split("<")); ArrayList preferList = new ArrayList<>(list); NetworkInterface preferNetworkInterface = null; + boolean isInterfacePreferred = false; try { Enumeration enumeration1 = NetworkInterface.getNetworkInterfaces(); while (enumeration1.hasMoreElements()) { final NetworkInterface networkInterface = enumeration1.nextElement(); + String interfaceName = networkInterface.getName(); + if (!isInterfacePreferred && preferList.contains(interfaceName)) { + isInterfacePreferred = true; + } if (preferNetworkInterface == null) { preferNetworkInterface = networkInterface; - } else if (preferList.indexOf(networkInterface.getName()) //get the networkInterface that has higher priority + } else if (preferList.indexOf(interfaceName) // get the networkInterface that has higher priority > preferList.indexOf(preferNetworkInterface.getName())) { preferNetworkInterface = networkInterface; } @@ -76,7 +81,7 @@ public static String getLocalAddress() { ArrayList ipv4Result = new ArrayList(); ArrayList ipv6Result = new ArrayList(); - if (preferNetworkInterface != null) { + if (preferNetworkInterface != null && isInterfacePreferred) { final Enumeration en = preferNetworkInterface.getInetAddresses(); getIpResult(ipv4Result, ipv6Result, en); } else { @@ -100,7 +105,7 @@ public static String getLocalAddress() { } else if (!ipv6Result.isEmpty()) { return ipv6Result.get(0); } - //If failed to find,fall back to localhost + // If failed to find,fall back to localhost final InetAddress localHost = InetAddress.getLocalHost(); return normalizeHostAddress(localHost); } catch (SocketException | UnknownHostException e) { @@ -112,12 +117,10 @@ public static String getLocalAddress() { public static boolean isValidIPV4Address(String ip) { // Regex for digit from 0 to 255. - String zeroTo255 - = "(\\d{1,2}|(0|1)\\" + String zeroTo255 = "(\\d{1,2}|(0|1)\\" + "d{2}|2[0-4]\\d|25[0-5])"; - String regex - = zeroTo255 + "\\." + String regex = zeroTo255 + "\\." + zeroTo255 + "\\." + zeroTo255 + "\\." + zeroTo255; @@ -136,7 +139,7 @@ public static boolean isValidIPV4Address(String ip) { return m.matches(); } - private static void getIpResult(List ipv4Result, List ipv6Result, Enumeration en) { + private static void getIpResult(Collection ipv4Result, Collection ipv6Result, Enumeration en) { while (en.hasMoreElements()) { final InetAddress address = en.nextElement(); if (!address.isLoopbackAddress()) { @@ -157,7 +160,6 @@ private static String normalizeHostAddress(final InetAddress localHost) { } } - public static String parseChannelRemoteAddr(final Channel channel) { if (null == channel) { return ""; diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonPathUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonPathUtils.java new file mode 100644 index 0000000000..175b322a80 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/JsonPathUtils.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.common.utils; + +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.exception.JsonException; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Strings; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.InvalidPathException; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.ReadContext; +import com.jayway.jsonpath.internal.path.CompiledPath; +import com.jayway.jsonpath.internal.path.PathCompiler; +import com.jayway.jsonpath.spi.json.JacksonJsonProvider; + +public class JsonPathUtils { + + public static final String JSONPATH_SPLIT = "\\."; + public static final String JSONPATH_PREFIX = "$"; + public static final String JSONPATH_PREFIX_WITH_POINT = "$."; + public static final String JSONPATH_DATA = "$.data"; + private static final ObjectMapper STRICT_OBJECT_MAPPER = new ObjectMapper(); + + private static final Configuration JSON_PATH_CONFIG = Configuration.builder() + .jsonProvider(new JacksonJsonProvider(STRICT_OBJECT_MAPPER)) + .build(); + + public static boolean isEmptyJsonObject(String jsonString) { + try { + JsonNode jsonNode = STRICT_OBJECT_MAPPER.readTree(jsonString); + return jsonNode.isObject() && jsonNode.isEmpty(); + } catch (Exception e) { + throw new JsonException("INVALID_JSON_STRING", e); + } + } + + public static JsonNode parseStrict(String json) throws JsonException { + try { + JsonParser parser = STRICT_OBJECT_MAPPER.getFactory().createParser(json); + JsonNode result = STRICT_OBJECT_MAPPER.readTree(parser); + if (parser.nextToken() != null) { + // Check if there are more tokens after reading the root object + throw new JsonException("Additional tokens found after parsing: " + json); + } + return result; + } catch (Exception e) { + throw new JsonException("Json is not valid in strict way: " + json, e); + } + } + + public static String buildJsonString(String key, Object value) { + Map map = new HashMap<>(); + map.put(key, value); + + ObjectMapper objectMapper = new ObjectMapper(); + try { + return objectMapper.writeValueAsString(map); + } catch (JsonProcessingException e) { + return null; + } + } + + public static boolean isValidAndDefinite(String jsonPath) { + if (Strings.isNullOrEmpty(jsonPath) || !jsonPath.startsWith(JSONPATH_PREFIX)) { + return Boolean.FALSE; + } + CompiledPath compiledPath = null; + try { + compiledPath = (CompiledPath) PathCompiler.compile(jsonPath); + } catch (InvalidPathException e) { + return Boolean.FALSE; + } + return compiledPath.isDefinite(); + } + + public static String getJsonPathValue(String content, String jsonPath) { + if (Strings.isNullOrEmpty(content) || Strings.isNullOrEmpty(jsonPath)) { + throw new EventMeshException("invalid config" + jsonPath); + } + Object obj = null; + try { + obj = JsonPath.using(JSON_PATH_CONFIG).parse(content).read(jsonPath, JsonNode.class); + } catch (InvalidPathException invalidPathException) { + return null; + } + return obj.toString(); + } + + public static JsonNode convertToJsonNode(String object) throws JsonProcessingException { + return STRICT_OBJECT_MAPPER.readValue(object, JsonNode.class); + } + + public static String matchJsonPathValueWithString(String jsonString, String jsonPath) { + Object obj = jsonPathParse(jsonString, jsonPath); + + if (obj == null) { + return "null"; + } + + return obj.toString(); + } + + public static Object jsonPathParse(String jsonString, String jsonPath) { + if (Strings.isNullOrEmpty(jsonPath) || Strings.isNullOrEmpty(jsonString)) { + throw new EventMeshException("invalid config" + jsonPath); + } + Object obj = null; + try { + final ReadContext readContext = JsonPath.using(JSON_PATH_CONFIG).parse(jsonString); + obj = readContext.read(jsonPath); + } catch (InvalidPathException invalidPathException) { + return null; + } + return obj; + } + + public static String matchJsonPathValue(String jsonString, String jsonPath) throws JsonProcessingException { + Object obj = jsonPathParse(jsonString, jsonPath); + return STRICT_OBJECT_MAPPER.writer().writeValueAsString(obj); + } +} 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 index 58a0571ee8..19614714fd 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.common.utils; - import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.EventMeshDateFormat; import org.apache.eventmesh.common.exception.JsonException; @@ -25,6 +24,7 @@ import org.apache.commons.lang3.StringUtils; import java.io.IOException; +import java.lang.reflect.Type; import java.util.Objects; import com.fasterxml.jackson.annotation.JsonInclude; @@ -34,6 +34,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; /** * Json serialize or deserialize utils. @@ -48,6 +49,7 @@ public class JsonUtils { OBJECT_MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); OBJECT_MAPPER.setDateFormat(new EventMeshDateFormat(Constants.DATE_FORMAT_DEFAULT)); OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); + OBJECT_MAPPER.registerModule(new JavaTimeModule()); } /** @@ -97,6 +99,24 @@ public static T parseObject(String text, Class clazz) { } } + public static T parseObject(String text, Type type) { + if (StringUtils.isEmpty(text)) { + return null; + } + try { + TypeReference typeReference = new TypeReference() { + + @Override + public Type getType() { + return type; + } + }; + return OBJECT_MAPPER.readValue(text, typeReference); + } catch (JsonProcessingException e) { + throw new JsonException("deserialize json string to object error", e); + } + } + public static T parseObject(byte[] bytes, Class clazz) { if (bytes == null || bytes.length == 0) { return null; diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/LogUtil.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/LogUtil.java new file mode 100644 index 0000000000..8c8dec2122 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/LogUtil.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.utils; + +import java.util.function.Supplier; + +import org.slf4j.Logger; +import org.slf4j.spi.CallerBoundaryAware; +import org.slf4j.spi.LoggingEventBuilder; + +import lombok.experimental.UtilityClass; + +/** + * This class provides logging methods that encapsulate SLF4J and Supplier. + * If the log level is not enabled, the passed Supplier is invoked lazily, + * thereby avoiding unnecessary method execution time. + *

+ * The statement + *

+ * {@code
+ * LogUtil.debug(log, "A time-consuming method: {}", () -> myMethod());
+ * }
+ * 
+ * is equivalent to: + *
+ * {@code
+ * if (logger.isDebugEnabled()) {
+ *     logger.debug("A time-consuming method: {}", myMethod());
+ * }
+ * }
+ * 
+ * If no object parameters are passed or existing objects are referenced, use + *
+ * {@code
+ * log.debug("No time-consuming methods: {}", myObject);
+ * }
+ * 
+ * instead. + */ + +@UtilityClass +public final class LogUtil { + + private static final String FQCN = LogUtil.class.getName(); + + public static void debug(Logger logger, String format, Supplier objectSupplier) { + final LoggingEventBuilder builder = logger.atDebug(); + if (builder instanceof CallerBoundaryAware) { + ((CallerBoundaryAware) builder).setCallerBoundary(FQCN); + } + builder.addArgument(objectSupplier).log(format); + } + + public static void debug(Logger logger, String format, Supplier objectSupplier, Throwable t) { + final LoggingEventBuilder builder = logger.atDebug(); + if (builder instanceof CallerBoundaryAware) { + ((CallerBoundaryAware) builder).setCallerBoundary(FQCN); + } + builder.addArgument(objectSupplier).setCause(t).log(format); + } + + public static void debug(Logger logger, String format, Supplier... objectSuppliers) { + LoggingEventBuilder builder = logger.atDebug(); + if (builder instanceof CallerBoundaryAware) { + ((CallerBoundaryAware) builder).setCallerBoundary(FQCN); + } + for (Supplier objectSupplier : objectSuppliers) { + builder = builder.addArgument(objectSupplier); + } + builder.log(format); + } + + public static void info(Logger logger, String format, Supplier objectSupplier) { + final LoggingEventBuilder builder = logger.atInfo(); + if (builder instanceof CallerBoundaryAware) { + ((CallerBoundaryAware) builder).setCallerBoundary(FQCN); + } + builder.addArgument(objectSupplier).log(format); + } + + public static void info(Logger logger, String format, Supplier objectSupplier, Throwable t) { + final LoggingEventBuilder builder = logger.atInfo(); + if (builder instanceof CallerBoundaryAware) { + ((CallerBoundaryAware) builder).setCallerBoundary(FQCN); + } + builder.addArgument(objectSupplier).setCause(t).log(format); + } + + public static void info(Logger logger, String format, Supplier... objectSuppliers) { + LoggingEventBuilder builder = logger.atInfo(); + if (builder instanceof CallerBoundaryAware) { + ((CallerBoundaryAware) builder).setCallerBoundary(FQCN); + } + for (Supplier objectSupplier : objectSuppliers) { + builder = builder.addArgument(objectSupplier); + } + builder.log(format); + } + + public static void warn(Logger logger, String format, Supplier objectSupplier) { + final LoggingEventBuilder builder = logger.atWarn(); + if (builder instanceof CallerBoundaryAware) { + ((CallerBoundaryAware) builder).setCallerBoundary(FQCN); + } + builder.addArgument(objectSupplier).log(format); + } + + public static void warn(Logger logger, String format, Supplier objectSupplier, Throwable t) { + final LoggingEventBuilder builder = logger.atWarn(); + if (builder instanceof CallerBoundaryAware) { + ((CallerBoundaryAware) builder).setCallerBoundary(FQCN); + } + builder.addArgument(objectSupplier).setCause(t).log(format); + } + + public static void warn(Logger logger, String format, Supplier... objectSuppliers) { + LoggingEventBuilder builder = logger.atWarn(); + if (builder instanceof CallerBoundaryAware) { + ((CallerBoundaryAware) builder).setCallerBoundary(FQCN); + } + for (Supplier objectSupplier : objectSuppliers) { + builder = builder.addArgument(objectSupplier); + } + builder.log(format); + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/NetUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/NetUtils.java index 0aae29c4eb..2c788d29b5 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/NetUtils.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/NetUtils.java @@ -30,8 +30,8 @@ import java.net.InetSocketAddress; import java.net.URLDecoder; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; import com.sun.net.httpserver.HttpExchange; @@ -71,7 +71,7 @@ public static Map formData2Dic(String formData) { return result; } - public static String addressToString(List clients) { + public static String addressToString(Collection clients) { if (clients.isEmpty()) { return "no session had been closed"; } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/PropertiesUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/PropertiesUtils.java index a691b312c3..ba7880ad04 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/PropertiesUtils.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/PropertiesUtils.java @@ -42,35 +42,34 @@ public static Properties getPropertiesByPrefix(final Properties from, final Stri } from.forEach((key, value) -> { - String keyStr = String.valueOf(key); - if (StringUtils.startsWith(keyStr, prefix)) { - String realKey = StringUtils.substring(keyStr, prefix.length()); - String[] hierarchicalKeys = StringUtils.split(realKey, Constants.DOT); - if (hierarchicalKeys != null) { - Properties hierarchical = to; - for (int idx = 0; idx < hierarchicalKeys.length; idx++) { - String hierarchicalKey = hierarchicalKeys[idx]; - if (StringUtils.isBlank(hierarchicalKey)) { - return; - } - if (idx < hierarchicalKeys.length - 1) { - Object pending = hierarchical.get(hierarchicalKey); - if (pending == null) { - hierarchical.put(hierarchicalKey, hierarchical = new Properties()); - } else if (pending instanceof Properties) { - hierarchical = (Properties) pending; - } else { - // Not Properties No need to parse anymore. - return; - } + String keyStr = String.valueOf(key); + if (StringUtils.startsWith(keyStr, prefix)) { + String realKey = StringUtils.substring(keyStr, prefix.length()); + String[] hierarchicalKeys = StringUtils.split(realKey, Constants.DOT); + if (hierarchicalKeys != null) { + Properties hierarchical = to; + for (int idx = 0; idx < hierarchicalKeys.length; idx++) { + String hierarchicalKey = hierarchicalKeys[idx]; + if (StringUtils.isBlank(hierarchicalKey)) { + return; + } + if (idx < hierarchicalKeys.length - 1) { + Object pending = hierarchical.get(hierarchicalKey); + if (pending == null) { + hierarchical.put(hierarchicalKey, hierarchical = new Properties()); + } else if (pending instanceof Properties) { + hierarchical = (Properties) pending; } else { - hierarchical.put(hierarchicalKey, value); + // Not Properties No need to parse anymore. + return; } + } else { + hierarchical.put(hierarchicalKey, value); } } } } - ); + }); return to; } 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 index c18a7d3e5e..195d721809 100644 --- 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 @@ -19,6 +19,9 @@ import org.apache.commons.text.RandomStringGenerator; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + public class RandomStringUtils { private static final RandomStringGenerator RANDOM_NUM_GENERATOR = new RandomStringGenerator.Builder().withinRange('0', '9').build(); @@ -27,4 +30,8 @@ public static String generateNum(int length) { return RANDOM_NUM_GENERATOR.generate(length); } + public static String generateUUID() { + return new UUID(ThreadLocalRandom.current().nextLong(), ThreadLocalRandom.current().nextLong()).toString(); + } + } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/ReflectUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/ReflectUtils.java new file mode 100644 index 0000000000..7dd1205684 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/ReflectUtils.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.common.utils; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class ReflectUtils { + + /** + * Look up not private fields inherited from the parent class. + * + * @param clazz + * @param fieldName + * @return + */ + public static Field lookUpFieldByParentClass(Class clazz, String fieldName) { + Class superClass = clazz.getSuperclass(); + while (superClass != null) { + Field[] superFields = superClass.getDeclaredFields(); + for (Field superField : superFields) { + if (!Modifier.isPrivate(superField.getModifiers()) && superField.getName().equals(fieldName)) { + return superField; + } + } + superClass = superClass.getSuperclass(); + } + return null; + } +} diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/SystemUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/SystemUtils.java index 0cfe6f821e..c01dc8c2be 100644 --- a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/SystemUtils.java +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/SystemUtils.java @@ -53,7 +53,7 @@ public static boolean isWindowsPlatform() { public static String getProcessId() { try { - //likely works on most platforms + // likely works on most platforms final Class managementFactoryClass = Class.forName("java.lang.management.ManagementFactory"); final Method getRuntimeMXBean = managementFactoryClass.getDeclaredMethod("getRuntimeMXBean"); final Class runtimeMXBeanClass = Class.forName("java.lang.management.RuntimeMXBean"); 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 index 03f070ceb8..002530a542 100644 --- 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 @@ -34,7 +34,7 @@ public static void randomPause(long min, long max, TimeUnit timeUnit) { long timeout = ThreadLocalRandom.current().nextLong(min, max + 1); timeUnit.sleep(timeout); } catch (InterruptedException ignore) { - //ignore + Thread.currentThread().interrupt(); } } @@ -51,7 +51,7 @@ public static void sleep(long timeout, TimeUnit timeUnit) { try { sleepWithThrowException(timeout, timeUnit); } catch (InterruptedException ignore) { - //ignore + Thread.currentThread().interrupt(); } } diff --git a/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/TypeUtils.java b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/TypeUtils.java new file mode 100644 index 0000000000..bac2365a81 --- /dev/null +++ b/eventmesh-common/src/main/java/org/apache/eventmesh/common/utils/TypeUtils.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 java.util.HashSet; +import java.util.Set; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class TypeUtils { + + public static Set castSet(Object obj, Class clazz) { + Set result = new HashSet<>(); + if (obj instanceof Set) { + for (Object o : (Set) obj) { + result.add(clazz.cast(o)); + } + return result; + } + return null; + } +} 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 index eec95da3c6..d6a9a22325 100644 --- a/eventmesh-common/src/test/java/org/apache/eventmesh/common/EventMeshMessageTest.java +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/EventMeshMessageTest.java @@ -20,50 +20,50 @@ import java.util.HashMap; import java.util.Map; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class EventMeshMessageTest { @Test public void testGetProp() { - EventMeshMessage message = createLiteMessage(); - Assert.assertEquals(2L, message.getProp().size()); + EventMeshMessage message = createEventMeshMessage(); + Assertions.assertEquals(2L, message.getProp().size()); } @Test public void testSetProp() { - EventMeshMessage message = createLiteMessage(); + EventMeshMessage message = createEventMeshMessage(); Map prop = new HashMap<>(); prop.put("key3", "value3"); message.setProp(prop); - Assert.assertEquals(1L, message.getProp().size()); - Assert.assertEquals("value3", message.getProp("key3")); + Assertions.assertEquals(1L, message.getProp().size()); + Assertions.assertEquals("value3", message.getProp("key3")); } @Test public void testAddProp() { - EventMeshMessage message = createLiteMessage(); + EventMeshMessage message = createEventMeshMessage(); message.addProp("key3", "value3"); - Assert.assertEquals(3L, message.getProp().size()); - Assert.assertEquals("value1", message.getProp("key1")); + Assertions.assertEquals(3L, message.getProp().size()); + Assertions.assertEquals("value1", message.getProp("key1")); } @Test public void testGetPropKey() { - EventMeshMessage message = createLiteMessage(); - Assert.assertEquals("value1", message.getProp("key1")); + EventMeshMessage message = createEventMeshMessage(); + Assertions.assertEquals("value1", message.getProp("key1")); } @Test public void testRemoveProp() { - EventMeshMessage message = createLiteMessage(); + EventMeshMessage message = createEventMeshMessage(); message.removePropIfPresent("key1"); - Assert.assertEquals(1L, message.getProp().size()); - Assert.assertNull(message.getProp("key1")); + Assertions.assertEquals(1L, message.getProp().size()); + Assertions.assertNull(message.getProp("key1")); } - private EventMeshMessage createLiteMessage() { + private EventMeshMessage createEventMeshMessage() { Map prop = new HashMap<>(); prop.put("key1", "value1"); prop.put("key2", "value2"); diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/EventMeshThreadFactoryTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/EventMeshThreadFactoryTest.java index 944493260b..d0cd7d1d18 100644 --- a/eventmesh-common/src/test/java/org/apache/eventmesh/common/EventMeshThreadFactoryTest.java +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/EventMeshThreadFactoryTest.java @@ -17,8 +17,8 @@ package org.apache.eventmesh.common; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class EventMeshThreadFactoryTest { @@ -26,7 +26,7 @@ public class EventMeshThreadFactoryTest { public void testGetThreadNamePrefix() { final String threadNamePrefix = "threadNamePrefix"; EventMeshThreadFactory factory = new EventMeshThreadFactory(threadNamePrefix, false); - Assert.assertEquals(threadNamePrefix, factory.getThreadNamePrefix()); + Assertions.assertEquals(threadNamePrefix, factory.getThreadNamePrefix()); } @Test @@ -36,8 +36,8 @@ public void testNewThread() { Thread t = factory.newThread(() -> { }); - Assert.assertNotNull(t); - Assert.assertEquals(threadNamePrefix + "-1", t.getName()); - Assert.assertTrue(t.isDaemon()); + Assertions.assertNotNull(t); + Assertions.assertEquals(threadNamePrefix + "-1", t.getName()); + Assertions.assertTrue(t.isDaemon()); } } \ No newline at end of file diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/ResetCountDownLatchTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/ResetCountDownLatchTest.java new file mode 100644 index 0000000000..5b8cdce510 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/ResetCountDownLatchTest.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.common; + +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +public class ResetCountDownLatchTest { + + @Test + public void testConstructorParameterError() { + IllegalArgumentException e = Assertions.assertThrows(IllegalArgumentException.class, () -> new ResetCountDownLatch(-1)); + Assertions.assertEquals(e.getMessage(), "count must be greater than or equal to 0"); + ResetCountDownLatch resetCountDownLatch = new ResetCountDownLatch(1); + Assertions.assertEquals(1, resetCountDownLatch.getCount()); + } + + @Test + public void testAwaitTimeout() throws InterruptedException { + ResetCountDownLatch latch = new ResetCountDownLatch(1); + boolean await = latch.await(5, TimeUnit.MILLISECONDS); + Assertions.assertFalse(await); + latch.countDown(); + await = latch.await(5, TimeUnit.MILLISECONDS); + Assertions.assertTrue(await); + } + + @Test + @Timeout(1000) + public void testCountDownAndGetCount() throws InterruptedException { + int count = 2; + ResetCountDownLatch resetCountDownLatch = new ResetCountDownLatch(count); + Assertions.assertEquals(count, resetCountDownLatch.getCount()); + resetCountDownLatch.countDown(); + Assertions.assertEquals(count - 1, resetCountDownLatch.getCount()); + resetCountDownLatch.countDown(); + resetCountDownLatch.await(); + Assertions.assertEquals(0, resetCountDownLatch.getCount()); + } + + @Test + public void testReset() throws InterruptedException { + int count = 2; + ResetCountDownLatch resetCountDownLatch = new ResetCountDownLatch(count); + resetCountDownLatch.countDown(); + Assertions.assertEquals(count - 1, resetCountDownLatch.getCount()); + resetCountDownLatch.reset(); + Assertions.assertEquals(count, resetCountDownLatch.getCount()); + resetCountDownLatch.countDown(); + resetCountDownLatch.countDown(); + resetCountDownLatch.await(); + Assertions.assertEquals(0, resetCountDownLatch.getCount()); + resetCountDownLatch.countDown(); + Assertions.assertEquals(0, resetCountDownLatch.getCount()); + resetCountDownLatch.reset(); + resetCountDownLatch.countDown(); + Assertions.assertEquals(1, resetCountDownLatch.getCount()); + + } +} \ No newline at end of file diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/ThreadWrapperTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/ThreadWrapperTest.java new file mode 100644 index 0000000000..a4f2a60f73 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/ThreadWrapperTest.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; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ThreadWrapperTest { + + @Test + public void getThreadName() { + ThreadWrapper wrapper = createThreadWrapper(false); + wrapper.start(); + Assertions.assertEquals("EventMesh-Wrapper-mxsm", wrapper.thread.getName()); + } + + @Test + public void start() { + ThreadWrapper wrapper = createThreadWrapper(false); + wrapper.start(); + Assertions.assertTrue(wrapper.isStated()); + } + + @Test + @Timeout(1000) + public void await() { + ThreadWrapper wrapper = createThreadWrapper(false); + wrapper.start(); + wrapper.await(1, TimeUnit.MILLISECONDS); + Assertions.assertFalse(wrapper.hasWakeup.get()); + wrapper.wakeup(); + Assertions.assertTrue(wrapper.hasWakeup.get()); + wrapper.await(); + Assertions.assertFalse(wrapper.hasWakeup.get()); + wrapper.await(2, TimeUnit.MILLISECONDS); + + } + + @Test + public void wakeup() { + } + + @Test + public void shutdown() { + AtomicInteger counter = new AtomicInteger(); + ThreadWrapper wrapper = new ThreadWrapper() { + + @Override + public String getThreadName() { + return "EventMesh-Wrapper-mxsm"; + } + + @Override + public void run() { + try { + TimeUnit.MILLISECONDS.sleep(500); + } catch (InterruptedException e) { + log.error("[ThreadWrapperTest][shutdown] InterruptedException", e); + } + counter.set(100); + } + }; + wrapper.start(); + wrapper.shutdown(); + Assertions.assertEquals(100, counter.get()); + } + + @Test + public void shutdownImmediately() { + AtomicInteger counter = new AtomicInteger(); + ThreadWrapper wrapper = new ThreadWrapper() { + + @Override + public String getThreadName() { + return "EventMesh-Wrapper-mxsm"; + } + + @Override + public void run() { + try { + TimeUnit.SECONDS.sleep(100); + } catch (InterruptedException e) { + return; + } + counter.set(100); + } + }; + wrapper.start(); + wrapper.shutdownImmediately(); + Assertions.assertEquals(0, counter.get()); + } + + @Test + public void setDaemon() { + ThreadWrapper threadWrapper = createThreadWrapper(true); + threadWrapper.start(); + Assertions.assertTrue(threadWrapper.thread.isDaemon()); + + ThreadWrapper threadWrapper1 = createThreadWrapper(false); + threadWrapper1.start(); + Assertions.assertFalse(threadWrapper1.thread.isDaemon()); + } + + private ThreadWrapper createThreadWrapper(boolean daemon) { + ThreadWrapper wrapper = new ThreadWrapper() { + + @Override + public String getThreadName() { + return "EventMesh-Wrapper-mxsm"; + } + + @Override + public void run() { + // nothing to do + } + }; + wrapper.setDaemon(daemon); + return wrapper; + } +} 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 index acc9327bba..11265522a7 100644 --- 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 @@ -20,15 +20,15 @@ import java.util.ArrayList; import java.util.List; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class CommonConfigurationTest { public CommonConfiguration config; - @Before + @BeforeEach public void beforeCommonConfigurationTest() throws Exception { ConfigService configService = ConfigService.getInstance(); configService.setRootConfig("classPath://configuration.properties"); @@ -40,40 +40,40 @@ public void beforeCommonConfigurationTest() throws Exception { @Test public void testGetCommonConfiguration() { - Assert.assertEquals("env-succeed!!!", config.getEventMeshEnv()); - Assert.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); - Assert.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); - Assert.assertEquals("name-succeed!!!", config.getEventMeshName()); - Assert.assertEquals("816", config.getSysID()); - //Assert.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); - Assert.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); - Assert.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); - Assert.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); - Assert.assertEquals("registry-succeed!!!", config.getEventMeshRegistryPluginType()); - Assert.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); - Assert.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); - Assert.assertEquals("username-succeed!!!", config.getEventMeshRegistryPluginUsername()); - Assert.assertEquals("password-succeed!!!", config.getEventMeshRegistryPluginPassword()); + Assertions.assertEquals("env-succeed!!!", config.getEventMeshEnv()); + Assertions.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); + Assertions.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); + Assertions.assertEquals("name-succeed!!!", config.getEventMeshName()); + Assertions.assertEquals("816", config.getSysID()); + // Assertions.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); + Assertions.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); + Assertions.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); + Assertions.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); + Assertions.assertEquals("metaStorage-succeed!!!", config.getEventMeshMetaStoragePluginType()); + Assertions.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); + Assertions.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); + Assertions.assertEquals("username-succeed!!!", config.getEventMeshMetaStoragePluginUsername()); + Assertions.assertEquals("password-succeed!!!", config.getEventMeshMetaStoragePluginPassword()); - Assert.assertEquals(Integer.valueOf(816), config.getEventMeshRegisterIntervalInMills()); - Assert.assertEquals(Integer.valueOf(1816), config.getEventMeshFetchRegistryAddrInterval()); + Assertions.assertEquals(Integer.valueOf(816), config.getEventMeshMetaStorageIntervalInMills()); + Assertions.assertEquals(Integer.valueOf(1816), config.getEventMeshFetchMetaStorageAddrInterval()); List list = new ArrayList<>(); list.add("metrics-succeed1!!!"); list.add("metrics-succeed2!!!"); list.add("metrics-succeed3!!!"); - Assert.assertEquals(list, config.getEventMeshMetricsPluginType()); + Assertions.assertEquals(list, config.getEventMeshMetricsPluginType()); List list1 = new ArrayList<>(); list1.add("TCP"); list1.add("HTTP"); list1.add("GRPC"); - Assert.assertEquals(list1, config.getEventMeshProvideServerProtocols()); + Assertions.assertEquals(list1, config.getEventMeshProvideServerProtocols()); - Assert.assertTrue(config.isEventMeshServerSecurityEnable()); - Assert.assertTrue(config.isEventMeshServerRegistryEnable()); - Assert.assertTrue(config.isEventMeshServerTraceEnable()); + Assertions.assertTrue(config.isEventMeshServerSecurityEnable()); + Assertions.assertTrue(config.isEventMeshServerMetaStorageEnable()); + Assertions.assertTrue(config.isEventMeshServerTraceEnable()); - Assert.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); + Assertions.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/ConfigServiceTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/ConfigServiceTest.java index 7457933ce1..992800625c 100644 --- a/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/ConfigServiceTest.java +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/config/ConfigServiceTest.java @@ -22,8 +22,8 @@ import java.io.File; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class ConfigServiceTest { @@ -86,6 +86,6 @@ public void getConfigByConfigPath() throws Exception { } public void assertCommonConfiguration(CommonConfiguration config) { - Assert.assertEquals("env-succeed!!!", config.getEventMeshEnv()); + Assertions.assertEquals("env-succeed!!!", config.getEventMeshEnv()); } } 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 index 63448220ca..0d3163de44 100644 --- 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 @@ -17,45 +17,53 @@ package org.apache.eventmesh.common.file; -import org.apache.eventmesh.common.utils.ThreadUtils; - import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Files; import java.util.Properties; -import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.ArgumentMatcher; +import org.mockito.Mockito; public class WatchFileManagerTest { + @TempDir + File tempConfigDir; + @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); + File configFile = new File(file); + File tempConfigFile = new File(tempConfigDir, "configuration.properties"); + Files.copy(configFile.toPath(), tempConfigFile.toPath()); + + final FileChangeListener mockFileChangeListener = Mockito.mock(FileChangeListener.class); + Mockito.when(mockFileChangeListener.support( + Mockito.argThat(isFileUnderTest(tempConfigFile.getParent(), tempConfigFile.getName()))) + ).thenReturn(true); + + WatchFileManager.registerFileChangeListener(tempConfigFile.getParent(), mockFileChangeListener); 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"); + try (BufferedReader bufferedReader = new BufferedReader(new FileReader(tempConfigFile))) { + properties.load(bufferedReader); + } + + try (FileWriter fw = new FileWriter(tempConfigFile)) { + properties.setProperty("eventMesh.server.newAdd", "newAdd"); + properties.store(fw, "newAdd"); + } + + Mockito.verify(mockFileChangeListener, Mockito.timeout(15_000).atLeastOnce()) + .onChanged(Mockito.argThat(isFileUnderTest(tempConfigFile.getParent(), tempConfigFile.getName()))); + } - ThreadUtils.sleep(500, TimeUnit.MILLISECONDS); + private ArgumentMatcher isFileUnderTest(String directoryPath, String fileName) { + return argument -> argument.getDirectoryPath().equals(directoryPath) && argument.getFileName().equals(fileName); } } 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 index f01a136465..434e19f3b2 100644 --- 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 @@ -22,10 +22,9 @@ import java.util.List; import java.util.Map; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import lombok.extern.slf4j.Slf4j; @@ -34,7 +33,7 @@ public class RandomLoadBalanceSelectorTest { private RandomLoadBalanceSelector randomLoadBalanceSelector; - @Before + @BeforeEach public void befor() { List address = new ArrayList<>(); address.add("A"); @@ -43,7 +42,6 @@ public void befor() { randomLoadBalanceSelector = new RandomLoadBalanceSelector<>(address); } - @Test public void testSelect() { Map addressToNum = new HashMap<>(); @@ -53,11 +51,11 @@ public void testSelect() { } addressToNum.forEach((key, value) -> log.info("{} : {}", key, value)); // just assert success if no exception - Assert.assertTrue(true); + Assertions.assertTrue(true); } @Test public void testGetType() { - Assert.assertEquals(LoadBalanceType.RANDOM, randomLoadBalanceSelector.getType()); + Assertions.assertEquals(LoadBalanceType.RANDOM, randomLoadBalanceSelector.getType()); } } 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 index a5edd17eb2..89aaa7fbe4 100644 --- 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 @@ -27,9 +27,8 @@ import java.util.function.Function; import java.util.stream.IntStream; -import org.junit.Assert; -import org.junit.Test; - +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import lombok.extern.slf4j.Slf4j; @@ -43,7 +42,7 @@ public void testSelect() throws Exception { 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()); + Assertions.assertEquals(LoadBalanceType.WEIGHT_RANDOM, weightRandomLoadBalanceSelector.getType()); int testRange = 100_000; Map addressToNum = IntStream.range(0, testRange) .mapToObj(i -> weightRandomLoadBalanceSelector.select()) @@ -54,8 +53,8 @@ public void testSelect() throws Exception { }); log.info("addressToNum: {}", addressToNum); // 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); + Assertions.assertTrue(Math.abs(addressToNum.get("192.168.0.3") - addressToNum.get("192.168.0.2") * 2) < testRange / 20); + Assertions.assertTrue(Math.abs(addressToNum.get("192.168.0.3") - addressToNum.get("192.168.0.1") * 4) < testRange / 20); } @Test @@ -65,7 +64,7 @@ public void testSameWeightSelect() throws Exception { 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()); + Assertions.assertEquals(LoadBalanceType.WEIGHT_RANDOM, weightRandomLoadBalanceSelector.getType()); int testRange = 100_000; Map addressToNum = IntStream.range(0, testRange) @@ -75,12 +74,12 @@ public void testSameWeightSelect() throws Exception { Field field = WeightRandomLoadBalanceSelector.class.getDeclaredField("sameWeightGroup"); field.setAccessible(true); boolean sameWeightGroup = (boolean) field.get(weightRandomLoadBalanceSelector); - Assert.assertTrue(sameWeightGroup); + Assertions.assertTrue(sameWeightGroup); addressToNum.forEach((key, value) -> { log.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); + Assertions.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 index e7c3d3f6e7..dd49395711 100644 --- 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 @@ -22,20 +22,18 @@ import java.util.List; import java.util.Map; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import lombok.extern.slf4j.Slf4j; - @Slf4j public class WeightRoundRobinLoadBalanceSelectorTest { private WeightRoundRobinLoadBalanceSelector weightRoundRobinLoadBalanceSelector; - @Before + @BeforeEach public void before() { List> weightList = new ArrayList<>(); weightList.add(new Weight<>("A", 10)); @@ -54,12 +52,12 @@ public void testSelect() { addressToNum.forEach((key, value) -> { log.info("{}: {}", key, value); }); - Assert.assertTrue(addressToNum.get("B") > addressToNum.get("A")); - Assert.assertTrue(addressToNum.get("C") > addressToNum.get("B")); + Assertions.assertTrue(addressToNum.get("B") > addressToNum.get("A")); + Assertions.assertTrue(addressToNum.get("C") > addressToNum.get("B")); } @Test public void testGetType() { - Assert.assertEquals(LoadBalanceType.WEIGHT_ROUND_ROBIN, weightRoundRobinLoadBalanceSelector.getType()); + Assertions.assertEquals(LoadBalanceType.WEIGHT_ROUND_ROBIN, weightRoundRobinLoadBalanceSelector.getType()); } } 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 index bdf7a845f2..0aebc8bbdd 100644 --- 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 @@ -17,8 +17,8 @@ package org.apache.eventmesh.common.loadbalance; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class WeightTest { @@ -26,19 +26,19 @@ public class WeightTest { public void testDecreaseTotal() { Weight weight = new Weight(null, 0); weight.decreaseTotal(1); - Assert.assertEquals(-1, weight.getCurrentWeight().get()); + Assertions.assertEquals(-1, weight.getCurrentWeight().get()); } @Test public void testIncreaseCurrentWeight() { Weight weight = new Weight(null, 10); weight.increaseCurrentWeight(); - Assert.assertEquals(10, weight.getCurrentWeight().get()); + Assertions.assertEquals(10, weight.getCurrentWeight().get()); } @Test public void testGetCurrentWeight() { Weight weight = new Weight(null, 0); - Assert.assertEquals(0, weight.getCurrentWeight().get()); + Assertions.assertEquals(0, weight.getCurrentWeight().get()); } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/grpc/common/EventMeshCloudEventUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/grpc/common/EventMeshCloudEventUtilsTest.java new file mode 100644 index 0000000000..15c1af8a5d --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/grpc/common/EventMeshCloudEventUtilsTest.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.common.protocol.grpc.common; + +import org.apache.eventmesh.common.enums.EventMeshProtocolType; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; + +import java.net.URI; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.google.protobuf.Timestamp; + + +public class EventMeshCloudEventUtilsTest { + + private CloudEvent cloudEvent; + + @BeforeEach + public void init() { + + final Map attributeValueMap = new HashMap<>(64); + attributeValueMap.put(ProtocolKey.ENV, CloudEventAttributeValue.newBuilder().setCeString("dev").build()); + attributeValueMap.put(ProtocolKey.IDC, CloudEventAttributeValue.newBuilder().setCeString("eventmesh").build()); + attributeValueMap.put(ProtocolKey.IP, CloudEventAttributeValue.newBuilder().setCeString("127.0.0.1").build()); + attributeValueMap.put(ProtocolKey.PID, CloudEventAttributeValue.newBuilder().setCeString("1243").build()); + attributeValueMap.put(ProtocolKey.SYS, CloudEventAttributeValue.newBuilder().setCeString("eventmesh").build()); + attributeValueMap.put(ProtocolKey.LANGUAGE, CloudEventAttributeValue.newBuilder().setCeString("java").build()); + attributeValueMap.put(ProtocolKey.USERNAME, CloudEventAttributeValue.newBuilder().setCeString("mxsm").build()); + attributeValueMap.put(ProtocolKey.PASSWD, CloudEventAttributeValue.newBuilder().setCeString("mxsm").build()); + attributeValueMap.put(ProtocolKey.PROTOCOL_DESC, CloudEventAttributeValue.newBuilder().setCeString("version 1.0").build()); + attributeValueMap.put(ProtocolKey.SEQ_NUM, CloudEventAttributeValue.newBuilder().setCeString("100").build()); + attributeValueMap.put(ProtocolKey.UNIQUE_ID, CloudEventAttributeValue.newBuilder().setCeString("100").build()); + attributeValueMap.put(ProtocolKey.TTL, CloudEventAttributeValue.newBuilder().setCeString("100").build()); + attributeValueMap.put(ProtocolKey.PRODUCERGROUP, CloudEventAttributeValue.newBuilder().setCeString("mxsm_producer_group").build()); + attributeValueMap.put(ProtocolKey.TAG, CloudEventAttributeValue.newBuilder().setCeString("tag").build()); + attributeValueMap.put(ProtocolKey.SUBJECT, CloudEventAttributeValue.newBuilder().setCeString("topic").build()); + attributeValueMap.put(ProtocolKey.CLIENT_TYPE, CloudEventAttributeValue.newBuilder().setCeInteger(ClientType.SUB.getType()).build()); + attributeValueMap.put(ProtocolKey.GRPC_RESPONSE_CODE, CloudEventAttributeValue.newBuilder().setCeString("0").build()); + Instant instant = LocalDateTime.of(2023, 4, 11, 19, 7, 0).toInstant(ZoneOffset.UTC); + attributeValueMap.put(ProtocolKey.GRPC_RESPONSE_TIME, CloudEventAttributeValue.newBuilder() + .setCeTimestamp(Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build()).build()); + attributeValueMap.put(ProtocolKey.GRPC_RESPONSE_MESSAGE, CloudEventAttributeValue.newBuilder().setCeString("0").build()); + attributeValueMap.put(ProtocolKey.PROPERTY_MESSAGE_CLUSTER, CloudEventAttributeValue.newBuilder().setCeString("DefaultCluster").build()); + attributeValueMap.put(ProtocolKey.URL, CloudEventAttributeValue.newBuilder().setCeString("http://127.0.0.1").build()); + attributeValueMap.put(ProtocolKey.CONSUMERGROUP, CloudEventAttributeValue.newBuilder().setCeString("ConsumerGroup").build()); + attributeValueMap.put(ProtocolKey.DATA_CONTENT_TYPE, CloudEventAttributeValue.newBuilder().setCeString("text/plain").build()); + attributeValueMap.put(ProtocolKey.CONTENT_TYPE, CloudEventAttributeValue.newBuilder().setCeString("text/plain").build()); + attributeValueMap.put(ProtocolKey.PROTOCOL_TYPE, + CloudEventAttributeValue.newBuilder().setCeString(EventMeshProtocolType.CLOUD_EVENTS.protocolTypeName()).build()); + attributeValueMap.put(ProtocolKey.PROTOCOL_VERSION, CloudEventAttributeValue.newBuilder().setCeString("1.0").build()); + cloudEvent = CloudEvent.newBuilder().putAllAttributes(attributeValueMap).setId("123").setSource(URI.create("/").toString()) + .setType("eventmesh") + .setSpecVersion("1.0").setTextData("mxsm").build(); + } + + @Test + public void testGetEnv() { + Assertions.assertEquals("dev", EventMeshCloudEventUtils.getEnv(cloudEvent)); + Assertions.assertEquals("dev", EventMeshCloudEventUtils.getEnv(cloudEvent, "test")); + Assertions.assertEquals("test", EventMeshCloudEventUtils.getEnv(CloudEvent.newBuilder().build(), "test")); + } + + @Test + public void testGetIdc() { + Assertions.assertEquals("eventmesh", EventMeshCloudEventUtils.getIdc(cloudEvent)); + Assertions.assertEquals("eventmesh", EventMeshCloudEventUtils.getIdc(cloudEvent, "test")); + Assertions.assertEquals("test", EventMeshCloudEventUtils.getIdc(CloudEvent.newBuilder().build(), "test")); + } + + @Test + public void testGetSys() { + Assertions.assertEquals("eventmesh", EventMeshCloudEventUtils.getSys(cloudEvent)); + Assertions.assertEquals("eventmesh", EventMeshCloudEventUtils.getSys(cloudEvent, "test")); + Assertions.assertEquals("Linux", EventMeshCloudEventUtils.getSys(CloudEvent.newBuilder().build(), "Linux")); + } + + @Test + public void testGetPid() { + Assertions.assertEquals("1243", EventMeshCloudEventUtils.getPid(cloudEvent)); + Assertions.assertEquals("1243", EventMeshCloudEventUtils.getPid(cloudEvent, "test")); + Assertions.assertEquals("987", EventMeshCloudEventUtils.getPid(CloudEvent.newBuilder().build(), "987")); + } + + @Test + public void testGetIp() { + Assertions.assertEquals("127.0.0.1", EventMeshCloudEventUtils.getIp(cloudEvent)); + Assertions.assertEquals("127.0.0.1", EventMeshCloudEventUtils.getIp(cloudEvent, "127.0.0.2")); + Assertions.assertEquals("192.168.1.1", EventMeshCloudEventUtils.getIp(CloudEvent.newBuilder().build(), "192.168.1.1")); + } + + @Test + public void testGetUserName() { + Assertions.assertEquals("mxsm", EventMeshCloudEventUtils.getUserName(cloudEvent)); + Assertions.assertEquals("mxsm", EventMeshCloudEventUtils.getUserName(cloudEvent, "mxsm1")); + Assertions.assertEquals("root", EventMeshCloudEventUtils.getUserName(CloudEvent.newBuilder().build(), "root")); + } + + @Test + public void testGetPassword() { + Assertions.assertEquals("mxsm", EventMeshCloudEventUtils.getPassword(cloudEvent)); + Assertions.assertEquals("mxsm", EventMeshCloudEventUtils.getPassword(cloudEvent, "mxsm1")); + Assertions.assertEquals("root", EventMeshCloudEventUtils.getPassword(CloudEvent.newBuilder().build(), "root")); + } + + @Test + public void testGetLanguage() { + Assertions.assertEquals("java", EventMeshCloudEventUtils.getLanguage(cloudEvent)); + Assertions.assertEquals("java", EventMeshCloudEventUtils.getLanguage(cloudEvent, "Go")); + Assertions.assertEquals("Go", EventMeshCloudEventUtils.getLanguage(CloudEvent.newBuilder().build(), "Go")); + } + + @Test + public void testGetProtocolType() { + Assertions.assertEquals(EventMeshProtocolType.CLOUD_EVENTS.protocolTypeName(), EventMeshCloudEventUtils.getProtocolType(cloudEvent)); + Assertions.assertEquals(EventMeshProtocolType.CLOUD_EVENTS.protocolTypeName(), EventMeshCloudEventUtils.getProtocolType(cloudEvent, "Go")); + Assertions.assertEquals("eventmeshMessage", EventMeshCloudEventUtils.getProtocolType(CloudEvent.newBuilder().build(), "eventmeshMessage")); + } + + @Test + public void testGetProtocolVersion() { + Assertions.assertEquals("1.0", EventMeshCloudEventUtils.getProtocolVersion(cloudEvent)); + Assertions.assertEquals("1.0", EventMeshCloudEventUtils.getProtocolVersion(cloudEvent, "1.1")); + Assertions.assertEquals("1.2", EventMeshCloudEventUtils.getProtocolVersion(CloudEvent.newBuilder().build(), "1.2")); + } + + @Test + public void testGetProtocolDesc() { + Assertions.assertEquals("version 1.0", EventMeshCloudEventUtils.getProtocolDesc(cloudEvent)); + Assertions.assertEquals("version 1.0", EventMeshCloudEventUtils.getProtocolDesc(cloudEvent, "version 1.1")); + Assertions.assertEquals("version 1.2", EventMeshCloudEventUtils.getProtocolDesc(CloudEvent.newBuilder().build(), "version 1.2")); + } + + @Test + public void testGetSeqNum() { + Assertions.assertEquals("100", EventMeshCloudEventUtils.getSeqNum(cloudEvent)); + Assertions.assertEquals("100", EventMeshCloudEventUtils.getSeqNum(cloudEvent, "200")); + Assertions.assertEquals("200", EventMeshCloudEventUtils.getSeqNum(CloudEvent.newBuilder().build(), "200")); + } + + @Test + public void testGetUniqueId() { + Assertions.assertEquals("100", EventMeshCloudEventUtils.getUniqueId(cloudEvent)); + Assertions.assertEquals("100", EventMeshCloudEventUtils.getUniqueId(cloudEvent, "200")); + Assertions.assertEquals("200", EventMeshCloudEventUtils.getUniqueId(CloudEvent.newBuilder().build(), "200")); + } + + @Test + public void testGetTtl() { + Assertions.assertEquals("100", EventMeshCloudEventUtils.getTtl(cloudEvent)); + Assertions.assertEquals("100", EventMeshCloudEventUtils.getTtl(cloudEvent, "200")); + Assertions.assertEquals("200", EventMeshCloudEventUtils.getTtl(CloudEvent.newBuilder().build(), "200")); + } + + @Test + public void testGetProducerGroup() { + Assertions.assertEquals("mxsm_producer_group", EventMeshCloudEventUtils.getProducerGroup(cloudEvent)); + Assertions.assertEquals("mxsm_producer_group", EventMeshCloudEventUtils.getProducerGroup(cloudEvent, "mxsm_producer_group")); + Assertions.assertEquals("mxsm_producer_group1", + EventMeshCloudEventUtils.getProducerGroup(CloudEvent.newBuilder().build(), "mxsm_producer_group1")); + } + + @Test + public void testGetTag() { + Assertions.assertEquals("tag", EventMeshCloudEventUtils.getTag(cloudEvent)); + Assertions.assertEquals("tag", EventMeshCloudEventUtils.getTag(cloudEvent, "tag1")); + Assertions.assertEquals("tag1", EventMeshCloudEventUtils.getTag(CloudEvent.newBuilder().build(), "tag1")); + } + + @Test + public void testGetContentType() { + Assertions.assertEquals("text/plain", EventMeshCloudEventUtils.getContentType(cloudEvent)); + Assertions.assertEquals("text/plain", EventMeshCloudEventUtils.getContentType(cloudEvent, "application/json")); + Assertions.assertEquals("application/json", EventMeshCloudEventUtils.getContentType(CloudEvent.newBuilder().build(), "application/json")); + } + + @Test + public void testGetSubject() { + Assertions.assertEquals("topic", EventMeshCloudEventUtils.getSubject(cloudEvent)); + Assertions.assertEquals("topic", EventMeshCloudEventUtils.getSubject(cloudEvent, "topic12")); + Assertions.assertEquals("mxsm-topic", EventMeshCloudEventUtils.getSubject(CloudEvent.newBuilder().build(), "mxsm-topic")); + } + + @Test + public void testGetDataContentType() { + Assertions.assertEquals("text/plain", EventMeshCloudEventUtils.getDataContentType(cloudEvent)); + Assertions.assertEquals("text/plain", EventMeshCloudEventUtils.getDataContentType(cloudEvent, "application/json")); + Assertions.assertEquals("application/json", EventMeshCloudEventUtils.getDataContentType(CloudEvent.newBuilder().build(), "application/json")); + } + + @Test + public void testGetResponseCode() { + Assertions.assertEquals("0", EventMeshCloudEventUtils.getResponseCode(cloudEvent)); + Assertions.assertEquals("0", EventMeshCloudEventUtils.getResponseCode(cloudEvent, "1")); + Assertions.assertEquals("1", EventMeshCloudEventUtils.getResponseCode(CloudEvent.newBuilder().build(), "1")); + } + + @Test + public void testGetResponseMessage() { + Assertions.assertEquals("0", EventMeshCloudEventUtils.getResponseMessage(cloudEvent)); + Assertions.assertEquals("0", EventMeshCloudEventUtils.getResponseMessage(cloudEvent, "1")); + Assertions.assertEquals("1", EventMeshCloudEventUtils.getResponseMessage(CloudEvent.newBuilder().build(), "1")); + } + + @Test + public void testGetResponseTime() { + Assertions.assertEquals("2023-04-11T19:07Z", EventMeshCloudEventUtils.getResponseTime(cloudEvent)); + Assertions.assertEquals("2023-04-11T19:07Z", EventMeshCloudEventUtils.getResponseTime(cloudEvent, "2023-04-11 17:45:10")); + Assertions.assertEquals("1970-01-01T00:00Z", EventMeshCloudEventUtils.getResponseTime(CloudEvent.newBuilder().build(), "1970-01-01T00:00Z")); + } + + @Test + public void testGetCluster() { + Assertions.assertEquals("DefaultCluster", EventMeshCloudEventUtils.getCluster(cloudEvent)); + Assertions.assertEquals("DefaultCluster", EventMeshCloudEventUtils.getCluster(cloudEvent, "DefaultCluster1")); + Assertions.assertEquals("DefaultCluster1", EventMeshCloudEventUtils.getCluster(CloudEvent.newBuilder().build(), "DefaultCluster1")); + } + + @Test + public void testGetConsumerGroup() { + Assertions.assertEquals("ConsumerGroup", EventMeshCloudEventUtils.getConsumerGroup(cloudEvent)); + Assertions.assertEquals("ConsumerGroup", EventMeshCloudEventUtils.getConsumerGroup(cloudEvent, "ConsumerGroup111")); + Assertions.assertEquals("ConsumerGroup111", EventMeshCloudEventUtils.getConsumerGroup(CloudEvent.newBuilder().build(), "ConsumerGroup111")); + } + + @Test + public void testGetClientType() { + Assertions.assertEquals(ClientType.SUB, EventMeshCloudEventUtils.getClientType(cloudEvent)); + Assertions.assertEquals(ClientType.SUB, EventMeshCloudEventUtils.getClientType(cloudEvent, ClientType.PUB)); + Assertions.assertEquals(ClientType.PUB, EventMeshCloudEventUtils.getClientType(CloudEvent.newBuilder().build(), ClientType.PUB)); + } + + @Test + public void testGetURL() { + Assertions.assertEquals("http://127.0.0.1", EventMeshCloudEventUtils.getURL(cloudEvent)); + Assertions.assertEquals("http://127.0.0.1", EventMeshCloudEventUtils.getURL(cloudEvent, "http://127.0.0.2")); + Assertions.assertEquals("http://127.0.0.2", EventMeshCloudEventUtils.getURL(CloudEvent.newBuilder().build(), "http://127.0.0.2")); + } + + @Test + public void testGetDataContent() { + Assertions.assertEquals("mxsm", EventMeshCloudEventUtils.getDataContent(cloudEvent)); + Assertions.assertEquals("mxsm", EventMeshCloudEventUtils.getDataContent(cloudEvent, "http://127.0.0.2")); + Assertions.assertEquals("http://127.0.0.2", EventMeshCloudEventUtils.getDataContent(CloudEvent.newBuilder().build(), "http://127.0.0.2")); + } + + +} 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 index 962d6c7a79..ff1ec236ff 100644 --- 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 @@ -20,22 +20,23 @@ import static org.mockito.Mockito.when; 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.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.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.HttpHeaderNames; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class HttpCommandTest { @Mock @@ -46,7 +47,7 @@ public class HttpCommandTest { private HttpCommand httpCommand; - @Before + @BeforeEach public void before() { httpCommand = new HttpCommand("POST", "1.1", "200"); } @@ -57,36 +58,45 @@ public void testCreateHttpCommandResponseWithHeaderAndBody() { 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")); + Assertions.assertEquals("1.1", command.getHttpVersion()); + Assertions.assertEquals("POST", command.getHttpMethod()); + Assertions.assertEquals("200", command.getRequestCode()); + Assertions.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")); + Assertions.assertTrue(desc.startsWith("httpCommand")); } @Test public void testSimpleDesc() { HttpCommand command = httpCommand.createHttpCommandResponse(header, body); String desc = command.simpleDesc(); - Assert.assertTrue(desc.startsWith("httpCommand")); + Assertions.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)); + Assertions.assertEquals("keep-alive", response.headers().get(HttpHeaderNames.CONNECTION)); } @Test public void testHttpResponseWithREQCmdType() throws Exception { DefaultFullHttpResponse response = httpCommand.httpResponse(); - Assert.assertNull(response); + Assertions.assertNull(response); + } + + @Test + public void testCreateHttpCommandResponse() { + HttpCommand command = new HttpCommand(); + HttpCommand response = command.createHttpCommandResponse(EventMeshRetCode.SUCCESS); + Assertions.assertNotNull(response); + Assertions.assertEquals("0", response.getRequestCode()); + } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/HttpEventWrapperTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/HttpEventWrapperTest.java new file mode 100644 index 0000000000..d86ee09416 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/HttpEventWrapperTest.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; + +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.utils.JsonUtils; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +import io.netty.handler.codec.http.DefaultFullHttpResponse; + +@ExtendWith(MockitoExtension.class) +public class HttpEventWrapperTest { + + private HttpEventWrapper httpEventWrapper; + + @BeforeEach + public void setUp() { + httpEventWrapper = new HttpEventWrapper("POST", "1.1", "hello"); + } + + @Test + public void testCreateHttpResponse() { + HashMap headMap = new HashMap<>(); + headMap.put("String", "responseHeaderMap"); + HashMap responseBodyMap = new HashMap<>(); + responseBodyMap.put("String", "responseBodyMap"); + HttpEventWrapper result = httpEventWrapper.createHttpResponse(headMap, responseBodyMap); + Assertions.assertEquals("1.1", result.getHttpVersion()); + Assertions.assertEquals("POST", result.getHttpMethod()); + Assertions.assertEquals("hello", result.getRequestURI()); + Assertions.assertEquals("responseHeaderMap", result.getHeaderMap().get("String")); + Map responseMap = JsonUtils.parseObject(new String(result.getBody()), Map.class); + Assertions.assertEquals("responseBodyMap", responseMap.get("String")); + } + + @Test + public void testCreateHttpResponse2() { + HttpEventWrapper result = httpEventWrapper.createHttpResponse(EventMeshRetCode.SUCCESS); + Map responseMap = JsonUtils.parseObject(new String(result.getBody()), Map.class); + Assertions.assertEquals(EventMeshRetCode.SUCCESS.getRetCode(), responseMap.get("retCode")); + Assertions.assertEquals(EventMeshRetCode.SUCCESS.getErrMsg(), responseMap.get("retMessage")); + } + + @Test + public void testGetBody() { + byte[] bodyArray = new byte[]{'0'}; + httpEventWrapper.setBody(bodyArray); + byte[] result = httpEventWrapper.getBody(); + Assertions.assertNotNull(result); + Assertions.assertEquals(result[0], '0'); + } + + @Test + public void testSetBody() { + httpEventWrapper.setBody(new byte[]{(byte) 0}); + } + + @Test + public void testHttpResponse() throws Exception { + httpEventWrapper.setBody(new byte[]{(byte) 0}); + DefaultFullHttpResponse result = httpEventWrapper.httpResponse(); + Assertions.assertNotNull(result); + } + + @Test + public void testBuildSysHeaderForClient() { + httpEventWrapper.buildSysHeaderForClient(); + } + + @Test + public void testBuildSysHeaderForCE() { + httpEventWrapper.buildSysHeaderForCE(); + } +} 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 index 4a8850ba09..1564c41608 100644 --- 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 @@ -17,12 +17,10 @@ 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; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class BaseResponseBodyTest { @@ -31,10 +29,10 @@ 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")); + Assertions.assertTrue(body.toMap().containsKey(ProtocolKey.RETCODE)); + Assertions.assertTrue(body.toMap().containsKey(ProtocolKey.RETMSG)); + Assertions.assertTrue(body.toMap().containsKey(ProtocolKey.RESTIME)); + Assertions.assertEquals(200, body.toMap().get(ProtocolKey.RETCODE)); + Assertions.assertEquals("SUCCESS", body.toMap().get(ProtocolKey.RETMSG)); } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/body/BodyTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/body/BodyTest.java new file mode 100644 index 0000000000..7a26953ad8 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/body/BodyTest.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; + +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.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class BodyTest { + + private Map originalMap; + + @BeforeEach + public void before() { + originalMap = new HashMap<>(); + } + + @Test + public void testBuildBody() throws Exception { + Assertions.assertThrows(Exception.class, () -> Body.buildBody("-1", originalMap)); + Body sendMessageBatchRequestBody = Body.buildBody(String.valueOf(RequestCode.MSG_BATCH_SEND.getRequestCode()), originalMap); + Assertions.assertNotNull(sendMessageBatchRequestBody); + Assertions.assertEquals(sendMessageBatchRequestBody.getClass(), SendMessageBatchRequestBody.class); + Body sendMessageBatchV2RequestBody = Body.buildBody(String.valueOf(RequestCode.MSG_BATCH_SEND_V2.getRequestCode()), originalMap); + Assertions.assertNotNull(sendMessageBatchV2RequestBody); + Assertions.assertEquals(sendMessageBatchV2RequestBody.getClass(), SendMessageBatchV2RequestBody.class); + Body sendMessageRequestBodySync = Body.buildBody(String.valueOf(RequestCode.MSG_SEND_SYNC.getRequestCode()), originalMap); + Assertions.assertNotNull(sendMessageRequestBodySync); + Assertions.assertEquals(sendMessageRequestBodySync.getClass(), SendMessageRequestBody.class); + Body sendMessageRequestBodyAsync = Body.buildBody(String.valueOf(RequestCode.MSG_SEND_ASYNC.getRequestCode()), originalMap); + Assertions.assertNotNull(sendMessageRequestBodyAsync); + Assertions.assertEquals(sendMessageRequestBodyAsync.getClass(), SendMessageRequestBody.class); + Body pushMessageRequestBodySync = Body.buildBody(String.valueOf(RequestCode.HTTP_PUSH_CLIENT_SYNC.getRequestCode()), originalMap); + Assertions.assertNotNull(pushMessageRequestBodySync); + Assertions.assertEquals(pushMessageRequestBodySync.getClass(), PushMessageRequestBody.class); + Body pushMessageRequestBodyAsync = Body.buildBody(String.valueOf(RequestCode.HTTP_PUSH_CLIENT_ASYNC.getRequestCode()), originalMap); + Assertions.assertNotNull(pushMessageRequestBodyAsync); + Assertions.assertEquals(pushMessageRequestBodyAsync.getClass(), PushMessageRequestBody.class); + Body regRequestBody = Body.buildBody(String.valueOf(RequestCode.REGISTER.getRequestCode()), originalMap); + Assertions.assertNotNull(regRequestBody); + Assertions.assertEquals(regRequestBody.getClass(), RegRequestBody.class); + Body unRegRequestBody = Body.buildBody(String.valueOf(RequestCode.UNREGISTER.getRequestCode()), originalMap); + Assertions.assertNotNull(unRegRequestBody); + Assertions.assertEquals(unRegRequestBody.getClass(), UnRegRequestBody.class); + Body subscribeRequestBody = Body.buildBody(String.valueOf(RequestCode.SUBSCRIBE.getRequestCode()), originalMap); + Assertions.assertNotNull(subscribeRequestBody); + Assertions.assertEquals(subscribeRequestBody.getClass(), SubscribeRequestBody.class); + Body unSubscribeRequestBody = Body.buildBody(String.valueOf(RequestCode.UNSUBSCRIBE.getRequestCode()), originalMap); + Assertions.assertNotNull(unSubscribeRequestBody); + Assertions.assertEquals(unSubscribeRequestBody.getClass(), UnSubscribeRequestBody.class); + Body heartbeatRequestBody = Body.buildBody(String.valueOf(RequestCode.HEARTBEAT.getRequestCode()), originalMap); + Assertions.assertNotNull(heartbeatRequestBody); + Assertions.assertEquals(heartbeatRequestBody.getClass(), HeartbeatRequestBody.class); + Body replyMessageRequestBody = Body.buildBody(String.valueOf(RequestCode.REPLY_MESSAGE.getRequestCode()), originalMap); + Assertions.assertNotNull(replyMessageRequestBody); + Assertions.assertEquals(replyMessageRequestBody.getClass(), ReplyMessageRequestBody.class); + Body baseRequestBody = Body.buildBody(String.valueOf(RequestCode.ADMIN_SHUTDOWN.getRequestCode()), originalMap); + Assertions.assertNotNull(baseRequestBody); + Assertions.assertEquals(baseRequestBody.getClass(), BaseRequestBody.class); + } +} 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 index 4768963908..557807bfa8 100644 --- 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 @@ -17,16 +17,13 @@ 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; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class BaseRequestHeaderTest { @@ -35,7 +32,7 @@ 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")); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); + Assertions.assertEquals("200", header.toMap().get(ProtocolKey.REQUEST_CODE)); } } 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 index 23dc6540be..4d4021eb34 100644 --- 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 @@ -17,19 +17,17 @@ 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; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.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")); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); + Assertions.assertEquals("200", header.toMap().get(ProtocolKey.REQUEST_CODE)); } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/HeaderTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/HeaderTest.java new file mode 100644 index 0000000000..691e7d66e4 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/protocol/http/header/HeaderTest.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.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.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class HeaderTest { + + private Map originalMap; + + @BeforeEach + public void before() { + originalMap = new HashMap<>(); + } + + @Test + public void testBuildHeader() throws Exception { + Assertions.assertThrows(Exception.class, () -> Header.buildHeader("-1", originalMap)); + Header messageBatchRequestHeader = Header.buildHeader(String.valueOf(RequestCode.MSG_BATCH_SEND.getRequestCode()), originalMap); + Assertions.assertNotNull(messageBatchRequestHeader); + Assertions.assertEquals(messageBatchRequestHeader.getClass(), SendMessageBatchRequestHeader.class); + Header sendMessageBatchV2RequestHeader = Header.buildHeader(String.valueOf(RequestCode.MSG_BATCH_SEND_V2.getRequestCode()), originalMap); + Assertions.assertNotNull(sendMessageBatchV2RequestHeader); + Assertions.assertEquals(sendMessageBatchV2RequestHeader.getClass(), SendMessageBatchV2RequestHeader.class); + Header sendMessageRequestHeaderSync = Header.buildHeader(String.valueOf(RequestCode.MSG_SEND_SYNC.getRequestCode()), originalMap); + Assertions.assertNotNull(sendMessageRequestHeaderSync); + Assertions.assertEquals(sendMessageRequestHeaderSync.getClass(), SendMessageRequestHeader.class); + Header sendMessageRequestHeaderAsync = Header.buildHeader(String.valueOf(RequestCode.MSG_SEND_ASYNC.getRequestCode()), originalMap); + Assertions.assertNotNull(sendMessageRequestHeaderAsync); + Assertions.assertEquals(sendMessageRequestHeaderAsync.getClass(), SendMessageRequestHeader.class); + Header pushMessageRequestHeaderSync = Header.buildHeader(String.valueOf(RequestCode.HTTP_PUSH_CLIENT_SYNC.getRequestCode()), originalMap); + Assertions.assertNotNull(pushMessageRequestHeaderSync); + Assertions.assertEquals(pushMessageRequestHeaderSync.getClass(), PushMessageRequestHeader.class); + Header pushMessageRequestHeaderAsync = Header.buildHeader(String.valueOf(RequestCode.HTTP_PUSH_CLIENT_ASYNC.getRequestCode()), originalMap); + Assertions.assertNotNull(pushMessageRequestHeaderAsync); + Assertions.assertEquals(pushMessageRequestHeaderAsync.getClass(), PushMessageRequestHeader.class); + Header regRequestHeader = Header.buildHeader(String.valueOf(RequestCode.REGISTER.getRequestCode()), originalMap); + Assertions.assertNotNull(regRequestHeader); + Assertions.assertEquals(regRequestHeader.getClass(), RegRequestHeader.class); + Header unRegRequestHeader = Header.buildHeader(String.valueOf(RequestCode.UNREGISTER.getRequestCode()), originalMap); + Assertions.assertNotNull(unRegRequestHeader); + Assertions.assertEquals(unRegRequestHeader.getClass(), UnRegRequestHeader.class); + Header subscribeRequestHeader = Header.buildHeader(String.valueOf(RequestCode.SUBSCRIBE.getRequestCode()), originalMap); + Assertions.assertNotNull(subscribeRequestHeader); + Assertions.assertEquals(subscribeRequestHeader.getClass(), SubscribeRequestHeader.class); + Header unSubscribeRequestHeader = Header.buildHeader(String.valueOf(RequestCode.UNSUBSCRIBE.getRequestCode()), originalMap); + Assertions.assertNotNull(unSubscribeRequestHeader); + Assertions.assertEquals(unSubscribeRequestHeader.getClass(), UnSubscribeRequestHeader.class); + Header heartbeatRequestHeader = Header.buildHeader(String.valueOf(RequestCode.HEARTBEAT.getRequestCode()), originalMap); + Assertions.assertNotNull(heartbeatRequestHeader); + Assertions.assertEquals(heartbeatRequestHeader.getClass(), HeartbeatRequestHeader.class); + Header replyMessageRequestHeader = Header.buildHeader(String.valueOf(RequestCode.REPLY_MESSAGE.getRequestCode()), originalMap); + Assertions.assertNotNull(replyMessageRequestHeader); + Assertions.assertEquals(replyMessageRequestHeader.getClass(), ReplyMessageRequestHeader.class); + Header baseRequestHeader = Header.buildHeader(String.valueOf(RequestCode.ADMIN_SHUTDOWN.getRequestCode()), originalMap); + Assertions.assertNotNull(baseRequestHeader); + Assertions.assertEquals(baseRequestHeader.getClass(), BaseRequestHeader.class); + } +} 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 index 0726e6f07f..1d1ebc5925 100644 --- 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 @@ -20,20 +20,20 @@ import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; import org.apache.eventmesh.common.protocol.http.header.Header; -import org.junit.Assert; +import org.junit.jupiter.api.Assertions; 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)); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.LANGUAGE)); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.VERSION)); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.ENV.getKey())); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.IDC.getKey())); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.SYS.getKey())); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.PID.getKey())); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.IP.getKey())); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.USERNAME.getKey())); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.ClientInstanceKey.PASSWD.getKey())); } } 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 index 54e1f0c35d..d046321329 100644 --- 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 @@ -17,25 +17,23 @@ 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; +import org.junit.jupiter.api.Assertions; 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")); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.REQUEST_CODE)); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER)); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP)); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV)); + Assertions.assertTrue(header.toMap().containsKey(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC)); + Assertions.assertEquals(200, header.toMap().get(ProtocolKey.REQUEST_CODE)); + Assertions.assertEquals("CLUSTER", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER)); + Assertions.assertEquals("127.0.0.1", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP)); + Assertions.assertEquals("DEV", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV)); + Assertions.assertEquals("IDC", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC)); } } 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 index c09359e3f5..7a9f4c06cf 100644 --- 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 @@ -17,10 +17,9 @@ package org.apache.eventmesh.common.protocol.http.header.client; - import java.util.HashMap; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class HeartbeatRequestHeaderTest extends AbstractRequestHeaderTest { 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 index 79caba5a92..e4c208dc30 100644 --- 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 @@ -17,7 +17,7 @@ package org.apache.eventmesh.common.protocol.http.header.client; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class HeartbeatResponseHeaderTest extends AbstractResponseHeaderTest { 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 index 24f7eb3855..2a6eb76759 100644 --- 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 @@ -19,7 +19,7 @@ import java.util.HashMap; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class RegRequestHeaderTest extends AbstractRequestHeaderTest { 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 index e4ed364646..6f7ccfe868 100644 --- 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 @@ -17,7 +17,7 @@ package org.apache.eventmesh.common.protocol.http.header.client; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class RegResponseHeaderTest extends AbstractResponseHeaderTest { 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 index af79ff03fe..61b4dcba07 100644 --- 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 @@ -19,7 +19,7 @@ import java.util.HashMap; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class SubscribeRequestHeaderTest extends AbstractRequestHeaderTest { 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 index b2c9d9e889..3c9acba885 100644 --- 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 @@ -17,8 +17,7 @@ package org.apache.eventmesh.common.protocol.http.header.client; - -import org.junit.Test; +import org.junit.jupiter.api.Test; public class SubscribeResponseHeaderTest extends AbstractResponseHeaderTest { 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 index 50b8e8d6ea..90c1e3c164 100644 --- 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 @@ -17,10 +17,9 @@ package org.apache.eventmesh.common.protocol.http.header.client; - import java.util.HashMap; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class UnRegRequestHeaderTest extends AbstractRequestHeaderTest { 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 index c4acf1dcfc..6f30934f8d 100644 --- 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 @@ -17,7 +17,7 @@ package org.apache.eventmesh.common.protocol.http.header.client; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class UnRegResponseHeaderTest extends AbstractResponseHeaderTest { 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 index 562d92d83d..34d01d8f8f 100644 --- 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 @@ -19,7 +19,7 @@ import java.util.HashMap; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class UnSubscribeRequestHeaderTest extends AbstractRequestHeaderTest { 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 index 0750053342..f3b0e009a0 100644 --- 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 @@ -17,8 +17,7 @@ package org.apache.eventmesh.common.protocol.http.header.client; - -import org.junit.Test; +import org.junit.jupiter.api.Test; public class UnSubscribeResponseHeaderTest extends AbstractResponseHeaderTest { 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 index d683789578..05151d4dbe 100644 --- 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 @@ -17,8 +17,6 @@ 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; @@ -26,15 +24,15 @@ import java.util.HashMap; import java.util.Map; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class PushMessageRequestHeaderTest { private PushMessageRequestHeader header; - @Before + @BeforeEach public void before() { Map headerParam = new HashMap<>(); headerParam.put(ProtocolKey.REQUEST_CODE, 200); @@ -49,12 +47,12 @@ public void before() { @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")); + Assertions.assertEquals(200, header.toMap().get(ProtocolKey.REQUEST_CODE)); + Assertions.assertEquals(Constants.LANGUAGE_JAVA, header.toMap().get(ProtocolKey.LANGUAGE)); + Assertions.assertEquals(ProtocolVersion.V1, header.toMap().get(ProtocolKey.VERSION)); + Assertions.assertEquals("default cluster", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER)); + Assertions.assertEquals("127.0.0.1", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP)); + Assertions.assertEquals("DEV", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV)); + Assertions.assertEquals("IDC", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC)); } } 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 index 6b4673eb50..a23a5b7489 100644 --- 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 @@ -17,14 +17,12 @@ 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; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class PushMessageResponseHeaderTest { @@ -32,13 +30,13 @@ public class PushMessageResponseHeaderTest { 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")); + Assertions.assertEquals(100, header.toMap().get(ProtocolKey.REQUEST_CODE)); + Assertions.assertEquals(Constants.LANGUAGE_JAVA, header.toMap().get(ProtocolKey.LANGUAGE)); + Assertions.assertEquals(ProtocolVersion.V1, header.toMap().get(ProtocolKey.VERSION)); + Assertions.assertEquals("DEV", header.toMap().get(ProtocolKey.ClientInstanceKey.ENV.getKey())); + Assertions.assertEquals("IDC", header.toMap().get(ProtocolKey.ClientInstanceKey.IDC.getKey())); + Assertions.assertEquals("SYSID", header.toMap().get(ProtocolKey.ClientInstanceKey.SYS.getKey())); + Assertions.assertEquals("PID", header.toMap().get(ProtocolKey.ClientInstanceKey.PID.getKey())); + Assertions.assertEquals("127.0.0.1", header.toMap().get(ProtocolKey.ClientInstanceKey.IP.getKey())); } } 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 index eec5d1854d..a7a2049ba6 100644 --- 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 @@ -17,8 +17,6 @@ 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; @@ -26,37 +24,37 @@ import java.util.HashMap; import java.util.Map; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class ReplyMessageRequestHeaderTest { private ReplyMessageRequestHeader header; - @Before + @BeforeEach 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"); + headerParam.put(ProtocolKey.ClientInstanceKey.ENV.getKey(), "DEV"); + headerParam.put(ProtocolKey.ClientInstanceKey.IDC.getKey(), "IDC"); + headerParam.put(ProtocolKey.ClientInstanceKey.SYS.getKey(), "SYS"); + headerParam.put(ProtocolKey.ClientInstanceKey.PID.getKey(), "PID"); + headerParam.put(ProtocolKey.ClientInstanceKey.IP.getKey(), "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")); + Assertions.assertEquals("200", header.toMap().get(ProtocolKey.REQUEST_CODE)); + Assertions.assertEquals(Constants.LANGUAGE_JAVA, header.toMap().get(ProtocolKey.LANGUAGE)); + Assertions.assertEquals(ProtocolVersion.V1, header.toMap().get(ProtocolKey.VERSION)); + Assertions.assertEquals("DEV", header.toMap().get(ProtocolKey.ClientInstanceKey.ENV.getKey())); + Assertions.assertEquals("IDC", header.toMap().get(ProtocolKey.ClientInstanceKey.IDC.getKey())); + Assertions.assertEquals("SYS", header.toMap().get(ProtocolKey.ClientInstanceKey.SYS.getKey())); + Assertions.assertEquals("PID", header.toMap().get(ProtocolKey.ClientInstanceKey.PID.getKey())); + Assertions.assertEquals("127.0.0.1", header.toMap().get(ProtocolKey.ClientInstanceKey.IP.getKey())); } } 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 index c334ec5119..976c5529b7 100644 --- 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 @@ -17,12 +17,10 @@ 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; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class ReplyMessageResponseHeaderTest { @@ -30,10 +28,10 @@ public class ReplyMessageResponseHeaderTest { 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")); + Assertions.assertEquals(100, header.toMap().get(ProtocolKey.REQUEST_CODE)); + Assertions.assertEquals("Cluster", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER)); + Assertions.assertEquals("127.0.0.1", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP)); + Assertions.assertEquals("DEV", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV)); + Assertions.assertEquals("IDC", header.toMap().get(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC)); } } 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 index bb66e5c04b..19907ffd2b 100644 --- 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 @@ -20,11 +20,11 @@ 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.codec.Codec.Decoder; +import org.apache.eventmesh.common.protocol.tcp.codec.Codec.Encoder; -import java.util.ArrayList; - -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; @@ -37,14 +37,12 @@ public void testCodec() throws Exception { header.setCmd(Command.HELLO_REQUEST); Package testP = new Package(header); testP.setBody(new Object()); - Codec.Encoder ce = new Codec.Encoder(); + 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()); + Decoder cd = new Codec.Decoder(); + final Package decode = (Package) cd.decode(null, buf); + Assertions.assertEquals(testP.getHeader(), decode.getHeader()); } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/AssertTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/AssertTest.java deleted file mode 100644 index f6b0b1d547..0000000000 --- a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/AssertTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.common.utils; - -import org.junit.Test; - -/** - * test {@link AssertUtils} - */ -public class AssertTest { - - @Test(expected = IllegalArgumentException.class) - public void testNotNull() { - AssertUtils.notNull(null, "error message"); - } - - @Test(expected = IllegalArgumentException.class) - public void testIsTrue() { - AssertUtils.isTrue(false, "error message"); - } -} \ No newline at end of file diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/AssertUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/AssertUtilsTest.java new file mode 100644 index 0000000000..28040a76f6 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/AssertUtilsTest.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.common.utils; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * test {@link AssertUtils} + */ +public class AssertUtilsTest { + + @Test + public void testNotNull() { + Assertions.assertThrows(IllegalArgumentException.class, () -> AssertUtils.notNull(null, "error message")); + } + + @Test + public void testIsTrue() { + Assertions.assertThrows(IllegalArgumentException.class, () -> AssertUtils.isTrue(false, "error message")); + } +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/ConfigurationContextUtilTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/ConfigurationContextUtilTest.java new file mode 100644 index 0000000000..6ab7847d24 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/ConfigurationContextUtilTest.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.utils; + +import static org.apache.eventmesh.common.Constants.GRPC; +import static org.apache.eventmesh.common.Constants.TCP; + +import org.apache.eventmesh.common.config.CommonConfiguration; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class ConfigurationContextUtilTest { + + private CommonConfiguration grpcConfig; + + @BeforeEach + public void setUp() { + grpcConfig = new CommonConfiguration(); + grpcConfig.setEventMeshName("grpc"); + ConfigurationContextUtil.putIfAbsent(GRPC, grpcConfig); + } + + @Test + public void testPutIfAbsent() { + CommonConfiguration tcpConfig = new CommonConfiguration(); + tcpConfig.setEventMeshName("tpc"); + ConfigurationContextUtil.putIfAbsent(TCP, tcpConfig); + CommonConfiguration get = ConfigurationContextUtil.get(TCP); + Assertions.assertNotNull(get); + Assertions.assertEquals(tcpConfig, get); + CommonConfiguration newGrpc = new CommonConfiguration(); + newGrpc.setEventMeshName("newGrpc"); + ConfigurationContextUtil.putIfAbsent(GRPC, newGrpc); + CommonConfiguration getGrpc = ConfigurationContextUtil.get(GRPC); + Assertions.assertNotNull(getGrpc); + Assertions.assertEquals(grpcConfig, getGrpc); + Assertions.assertNotEquals(newGrpc, getGrpc); + } + + @Test + public void testGet() { + CommonConfiguration result = ConfigurationContextUtil.get(GRPC); + Assertions.assertNotNull(result); + Assertions.assertEquals(grpcConfig, result); + } + + @Test + public void testClear() { + CommonConfiguration result0 = ConfigurationContextUtil.get(GRPC); + Assertions.assertNotNull(result0); + ConfigurationContextUtil.clear(); + CommonConfiguration result = ConfigurationContextUtil.get(GRPC); + Assertions.assertNull(result); + } +} 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 index 4adff4475d..b3fa293e89 100644 --- 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 @@ -17,22 +17,21 @@ package org.apache.eventmesh.common.utils; -import org.junit.Assert; -import org.junit.Test; -import org.junit.contrib.java.lang.system.EnvironmentVariables; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.SetEnvironmentVariable; public class IPUtilsTest { @Test + @SetEnvironmentVariable(key = "docker_host_ip", value = "dockHostIP") public void testDockerIP() { - EnvironmentVariables environmentVariables = new EnvironmentVariables(); - environmentVariables.set("docker_host_ip", "dockHostIP"); - Assert.assertEquals("dockHostIP", IPUtils.getLocalAddress()); + Assertions.assertEquals("dockHostIP", IPUtils.getLocalAddress()); } @Test public void testLocalhostIP() { - Assert.assertNotNull(IPUtils.getLocalAddress()); + Assertions.assertNotNull(IPUtils.getLocalAddress()); } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/JsonUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/JsonUtilsTest.java index ba9a843308..264281a9a4 100644 --- a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/JsonUtilsTest.java +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/JsonUtilsTest.java @@ -18,14 +18,14 @@ package org.apache.eventmesh.common.utils; import java.nio.charset.StandardCharsets; +import java.time.LocalDate; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; -import org.junit.Assert; -import org.junit.Test; - +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; @@ -38,17 +38,22 @@ public class JsonUtilsTest { public void toJSONString() { Map map = new HashMap<>(); String jsonString = JsonUtils.toJSONString(map); - Assert.assertEquals("{}", jsonString); + Assertions.assertEquals("{}", jsonString); map.put("mxsm", "2"); jsonString = JsonUtils.toJSONString(map); - Assert.assertEquals("{\"mxsm\":\"2\"}", jsonString); + Assertions.assertEquals("{\"mxsm\":\"2\"}", jsonString); + + Map maps = new HashMap<>(); + maps.put("mxsm", LocalDate.of(2013, 6, 28)); + jsonString = JsonUtils.toJSONString(maps); + Assertions.assertEquals("{\"mxsm\":\"2013-06-28\"}", jsonString); } @Test public void testToBytes() { Map map = new HashMap<>(); map.put("mxsm", "2"); - Assert.assertArrayEquals("{\"mxsm\":\"2\"}".getBytes(StandardCharsets.UTF_8), JsonUtils.toJSONBytes(map)); + Assertions.assertArrayEquals("{\"mxsm\":\"2\"}".getBytes(StandardCharsets.UTF_8), JsonUtils.toJSONBytes(map)); } @Test @@ -58,24 +63,23 @@ public void testParseObject() { Map map = JsonUtils.parseTypeReferenceObject(json, new TypeReference>() { }); - Assert.assertNotNull(map); - Assert.assertEquals("2", map.get("mxsm")); + Assertions.assertNotNull(map); + Assertions.assertEquals("2", map.get("mxsm")); EventMesh mxsm = JsonUtils.parseObject(json, EventMesh.class); - Assert.assertNotNull(mxsm); - Assert.assertEquals("2", mxsm.mxsm); - Assert.assertEquals(new GregorianCalendar(2022, 1, 12, 21, 36, 01).getTime().getTime(), mxsm.date.getTime()); + Assertions.assertNotNull(mxsm); + Assertions.assertEquals("2", mxsm.mxsm); + Assertions.assertEquals(new GregorianCalendar(2022, 1, 12, 21, 36, 01).getTime().getTime(), mxsm.date.getTime()); EventMesh mxsm1 = JsonUtils.parseObject(json.getBytes(StandardCharsets.UTF_8), EventMesh.class); - Assert.assertNotNull(mxsm1); - Assert.assertEquals("2", mxsm1.mxsm); + Assertions.assertNotNull(mxsm1); + Assertions.assertEquals("2", mxsm1.mxsm); } - @Test public void getJsonNode() { String json = "{\"mxsm\":\"2\",\"date\":\"2022-02-12 21:36:01\"}"; JsonNode jsonNode = JsonUtils.getJsonNode(json); - Assert.assertNotNull(jsonNode); - Assert.assertEquals("2", jsonNode.findValue("mxsm").asText()); + Assertions.assertNotNull(jsonNode); + Assertions.assertEquals("2", jsonNode.findValue("mxsm").asText()); } @Data diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/NetUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/NetUtilsTest.java index 34d07a840e..91c0708394 100644 --- a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/NetUtilsTest.java +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/NetUtilsTest.java @@ -27,8 +27,8 @@ import java.util.List; import java.util.Map; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import com.sun.net.httpserver.HttpExchange; @@ -39,23 +39,23 @@ public class NetUtilsTest { public void testFormData2Dic() { String formData = ""; Map result = NetUtils.formData2Dic(formData); - Assert.assertTrue(result.isEmpty()); + Assertions.assertTrue(result.isEmpty()); formData = "item_id=10081&item_name=test item name"; result = NetUtils.formData2Dic(formData); - Assert.assertEquals("10081", result.get("item_id")); + Assertions.assertEquals("10081", result.get("item_id")); } @Test public void testAddressToString() { List clients = new ArrayList<>(); String result = NetUtils.addressToString(clients); - Assert.assertEquals("no session had been closed", result); + Assertions.assertEquals("no session had been closed", result); InetSocketAddress localAddress = new InetSocketAddress(80); clients.add(localAddress); result = NetUtils.addressToString(clients); - Assert.assertEquals(localAddress + "|", result); + Assertions.assertEquals(localAddress + "|", result); } @Test @@ -68,7 +68,7 @@ public void testParsePostBody() throws Exception { Mockito.when(exchange.getRequestBody()).thenReturn(inputStream); String actual = NetUtils.parsePostBody(exchange); - Assert.assertEquals(expected, actual); + Assertions.assertEquals(expected, actual); } @@ -77,6 +77,6 @@ public void testSendSuccessResponseHeaders() throws IOException { HttpExchange exchange = Mockito.mock(HttpExchange.class); NetUtils.sendSuccessResponseHeaders(exchange); Mockito.verify(exchange, Mockito.times(1)) - .sendResponseHeaders(Mockito.anyInt(), Mockito.anyLong()); + .sendResponseHeaders(Mockito.anyInt(), Mockito.anyLong()); } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/PropertiesUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/PropertiesUtilsTest.java index de29b85dab..1df563cf39 100644 --- a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/PropertiesUtilsTest.java +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/PropertiesUtilsTest.java @@ -21,8 +21,8 @@ import java.util.Properties; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class PropertiesUtilsTest { @@ -38,8 +38,8 @@ public void testGetPropertiesByPrefix() { from.put(PREFIX + "c.f", "inner f"); Properties to = PropertiesUtils.getPropertiesByPrefix(from, PREFIX); - Assert.assertEquals(3, to.size()); - Assert.assertEquals(2, ((Properties) to.get("c")).size()); + Assertions.assertEquals(3, to.size()); + Assertions.assertEquals(2, ((Properties) to.get("c")).size()); } @Test @@ -49,12 +49,8 @@ public void testLoadPropertiesWhenFileExist() throws Exception { configService.setRootConfig("classPath://configuration.properties"); properties = configService.getRootConfig(); String path = configService.getRootPath(); - try { - PropertiesUtils.loadPropertiesWhenFileExist(properties, path); - Assert.assertEquals("env-succeed!!!", properties.get("eventMesh.server.env").toString()); - Assert.assertEquals("idc-succeed!!!", properties.get("eventMesh.server.idc").toString()); - } catch (Exception e) { - Assert.fail(); - } + PropertiesUtils.loadPropertiesWhenFileExist(properties, path); + Assertions.assertEquals("env-succeed!!!", properties.get("eventMesh.server.env").toString()); + Assertions.assertEquals("idc-succeed!!!", properties.get("eventMesh.server.idc").toString()); } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/RandomStringUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/RandomStringUtilsTest.java new file mode 100644 index 0000000000..6356c2a303 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/RandomStringUtilsTest.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.utils; + +import org.apache.commons.lang3.math.NumberUtils; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class RandomStringUtilsTest { + + @Test + public void testGenerateNum() { + String result = RandomStringUtils.generateNum(2); + Assertions.assertTrue(NumberUtils.isDigits(result)); + Assertions.assertEquals(2, result.length()); + } + + @Test + public void testGenerateUUID() { + String result = RandomStringUtils.generateUUID(); + Assertions.assertTrue(result.matches("^\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}$")); + } + +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/ReflectUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/ReflectUtilsTest.java new file mode 100644 index 0000000000..769a40f336 --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/ReflectUtilsTest.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.utils; + +import java.lang.reflect.Field; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ReflectUtilsTest { + + public static class TestParent { + + private String age; + + public String tel; + + } + + public static class TestObj extends TestParent { + + private String name; + + private String password; + } + + @Test + public void testLookUpFieldByParentClass() { + Field fieldName = ReflectUtils.lookUpFieldByParentClass(TestObj.class, "name"); + Field fieldAge = ReflectUtils.lookUpFieldByParentClass(TestObj.class, "age"); + Field fieldTel = ReflectUtils.lookUpFieldByParentClass(TestObj.class, "tel"); + Assertions.assertNull(fieldName); + Assertions.assertNull(fieldAge); + Assertions.assertNotNull(fieldTel); + Assertions.assertEquals("tel", fieldTel.getName()); + } + +} diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/SystemUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/SystemUtilsTest.java index a14b1ee185..b941fee1d4 100644 --- a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/SystemUtilsTest.java +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/SystemUtilsTest.java @@ -17,29 +17,29 @@ package org.apache.eventmesh.common.utils; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class SystemUtilsTest { @Test public void isLinuxPlatform() { if (null != SystemUtils.OS_NAME && SystemUtils.OS_NAME.toLowerCase().contains("linux")) { - Assert.assertTrue(SystemUtils.isLinuxPlatform()); - Assert.assertFalse(SystemUtils.isWindowsPlatform()); + Assertions.assertTrue(SystemUtils.isLinuxPlatform()); + Assertions.assertFalse(SystemUtils.isWindowsPlatform()); } } @Test public void isWindowsPlatform() { if (null != SystemUtils.OS_NAME && SystemUtils.OS_NAME.toLowerCase().contains("windows")) { - Assert.assertFalse(SystemUtils.isLinuxPlatform()); - Assert.assertTrue(SystemUtils.isWindowsPlatform()); + Assertions.assertFalse(SystemUtils.isLinuxPlatform()); + Assertions.assertTrue(SystemUtils.isWindowsPlatform()); } } @Test public void getProcessId() { - Assert.assertNotEquals("-1", SystemUtils.getProcessId()); + Assertions.assertNotEquals("-1", SystemUtils.getProcessId()); } } diff --git a/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/TypeUtilsTest.java b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/TypeUtilsTest.java new file mode 100644 index 0000000000..fcd83642ec --- /dev/null +++ b/eventmesh-common/src/test/java/org/apache/eventmesh/common/utils/TypeUtilsTest.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 java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class TypeUtilsTest { + + @Test + public void testCastSet() { + Set set = new HashSet<>(Arrays.asList("1", "2", "3")); + Set newSet = TypeUtils.castSet(set, String.class); + for (String s : set) { + Assertions.assertTrue(newSet.contains(s)); + } + Assertions.assertEquals(set.size(), newSet.size()); + } +} diff --git a/eventmesh-common/src/test/resources/configuration.properties b/eventmesh-common/src/test/resources/configuration.properties index 74b5cc0253..f80bb7db01 100644 --- a/eventmesh-common/src/test/resources/configuration.properties +++ b/eventmesh-common/src/test/resources/configuration.properties @@ -23,17 +23,17 @@ eventMesh.server.hostIp=hostIp-succeed!!! eventMesh.connector.plugin.type=connector-succeed!!! eventMesh.storage.plugin.type=storage-succeed!!! eventMesh.security.plugin.type=security-succeed!!! -eventMesh.registry.plugin.type=registry-succeed!!! +eventMesh.metaStorage.plugin.type=metaStorage-succeed!!! eventMesh.trace.plugin=trace-succeed!!! -eventMesh.server.registry.registerIntervalInMills=816 -eventMesh.server.registry.fetchRegistryAddrIntervalInMills=1816 +eventMesh.metaStorage.plugin.metaStorageIntervalInMills=816 +eventMesh.metaStorage.plugin.fetchMetaStorageAddrIntervalInMills=1816 eventMesh.metrics.plugin=metrics-succeed1!!!,metrics-succeed2!!!,metrics-succeed3!!! -eventMesh.registry.plugin.server-addr=server-addr-succeed1!!! +eventMesh.metaStorage.plugin.server-addr=server-addr-succeed1!!! eventMesh.server.security.enabled=true -eventMesh.server.registry.enabled=true +eventMesh.metaStorage.plugin.enabled=true eventMesh.server.trace.enabled=true eventMesh.server.provide.protocols=TCP,HTTP,GRPC -eventMesh.registry.plugin.username=username-succeed!!! -eventMesh.registry.plugin.password=password-succeed!!! +eventMesh.metaStorage.plugin.username=username-succeed!!! +eventMesh.metaStorage.plugin.password=password-succeed!!! diff --git a/eventmesh-connectors/README.md b/eventmesh-connectors/README.md deleted file mode 100644 index 1cba277ea9..0000000000 --- a/eventmesh-connectors/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Connectors - -## Connector -A connector is a bridge that interacts with a specific external service or underlying data source (e.g., Databases) on behalf of user applications. A connector is either a Source or a Sink. - -## Source -A source connector obtains data from an underlying data producer and delivers it to targets, after original data has been transformed into CloudEvents. It doesn't limit the way how a source retrieves data. (e.g., A source may pull data from a message queue or act as an HTTP server waiting for data sent to it). - -## Sink -A sink connector receives CloudEvents and does some specific business logics. (e.g., A MySQL Sink extracts useful data from CloudEvents and writes them to a MySQL database). -CloudEvents - A specification for describing event data in common formats to provide interoperability across services, platforms and systems. - -## Implements -Add a new connector by implementing the source/sink interface using : - -[eventmesh-openconnect-java](https://github.com/apache/eventmesh/tree/master/eventmesh-openconnect/eventmesh-openconnect-java) - -## Connector Status - -| Connector Name | Type | Support Version | -|---------------------------------------|--------|-----------------| -| [RocketMQ](sink-connector-rocketmq) | Sink | N/A | -| [RocketMQ](source-connector-rocketmq) | Source | N/A | -| ChatGPT | Source | N/A | -| ClickHouse | Sink | N/A | -| ClickHouse | Source | N/A | -| DingTalk | Sink | N/A | -| Email | Sink | N/A | -| FeiShu | Sink | N/A | -| Github | Source | N/A | -| Http | Sink | N/A | -| Http | Source | N/A | -| Jdbc | Sink | N/A | -| Jdbc | Source | N/A | -| MySqlCDC | Source | N/A | -| MongoDB | Sink | N/A | -| MongoDB | Source | N/A | -| S3File | Sink | N/A | -| S3File | Source | N/A | -| More connectors will be added... | Source/Sink | N/A | diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/build.gradle b/eventmesh-connectors/eventmesh-connector-dingtalk/build.gradle new file mode 100644 index 0000000000..46d16c3b35 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/build.gradle @@ -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. + */ + +configurations { + implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' + implementation.exclude group: 'log4j', module: 'log4j' + testImplementation.exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j' +} + +dependencies { + implementation project(":eventmesh-common") + implementation project(":eventmesh-sdks:eventmesh-sdk-java") + implementation project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation "com.aliyun:dingtalk:2.0.61" + implementation 'com.google.guava:guava' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-junit-jupiter" +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/gradle.properties b/eventmesh-connectors/eventmesh-connector-dingtalk/gradle.properties new file mode 100644 index 0000000000..be63fc4f95 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/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=dingtalk \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/common/constants/ConnectRecordExtensionKeys.java b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/common/constants/ConnectRecordExtensionKeys.java new file mode 100644 index 0000000000..bb6292134b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/common/constants/ConnectRecordExtensionKeys.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.connector.dingtalk.common.constants; + +/** + * Constants of record extension key. + */ +public interface ConnectRecordExtensionKeys { + + String DINGTALK_TEMPLATE_TYPE = "dingtalktemplatetype"; + + String DINGTALK_MARKDOWN_MESSAGE_TITLE = "dingtalkmarkdownmessagetitle"; +} diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/config/DingDingConnectServerConfig.java b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/config/DingDingConnectServerConfig.java new file mode 100644 index 0000000000..ec744922c2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/config/DingDingConnectServerConfig.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.dingtalk.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class DingDingConnectServerConfig extends Config { + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/config/DingDingMessageTemplateType.java b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/config/DingDingMessageTemplateType.java new file mode 100644 index 0000000000..5c26066869 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/config/DingDingMessageTemplateType.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.connector.dingtalk.config; + +import java.util.Arrays; + +public enum DingDingMessageTemplateType { + + PLAIN_TEXT("text", "sampleText"), + MARKDOWN("markdown", "sampleMarkdown"); + + private final String templateType; + + private final String templateKey; + + DingDingMessageTemplateType(String templateType, String templateKey) { + this.templateType = templateType; + this.templateKey = templateKey; + } + + public String getTemplateType() { + return templateType; + } + + public String getTemplateKey() { + return templateKey; + } + + public static DingDingMessageTemplateType of(String templateType) { + return Arrays.stream(values()) + .filter(v -> v.getTemplateType().equals(templateType)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("TemplateType: " + templateType + " not found.")); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/server/DingDingConnectServer.java b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/server/DingDingConnectServer.java new file mode 100644 index 0000000000..a7ea6fad0b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/server/DingDingConnectServer.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.connector.dingtalk.server; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.dingtalk.config.DingDingConnectServerConfig; +import org.apache.eventmesh.connector.dingtalk.sink.connector.DingDingSinkConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +public class DingDingConnectServer { + + public static void main(String[] args) throws Exception { + + DingDingConnectServerConfig dingDingConnectServerConfig = ConfigUtil.parse(DingDingConnectServerConfig.class, + Constants.CONNECT_SERVER_CONFIG_FILE_NAME); + + if (dingDingConnectServerConfig.isSinkEnable()) { + Application application = new Application(); + application.run(DingDingSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/sink/config/DingDingSinkConfig.java b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/sink/config/DingDingSinkConfig.java new file mode 100644 index 0000000000..aa4245219f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/sink/config/DingDingSinkConfig.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.dingtalk.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class DingDingSinkConfig extends SinkConfig { + + private SinkConnectorConfig sinkConnectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..2211fd1adc --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/sink/config/SinkConnectorConfig.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.connector.dingtalk.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String appKey; + + private String appSecret; + + private String openConversationId; + + private String robotCode; + + private String coolAppCode; +} diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/sink/connector/DingDingSinkConnector.java b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/sink/connector/DingDingSinkConnector.java new file mode 100644 index 0000000000..ff41855e36 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/java/org/apache/eventmesh/connector/dingtalk/sink/connector/DingDingSinkConnector.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.connector.dingtalk.sink.connector; + +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.connector.dingtalk.common.constants.ConnectRecordExtensionKeys; +import org.apache.eventmesh.connector.dingtalk.config.DingDingMessageTemplateType; +import org.apache.eventmesh.connector.dingtalk.sink.config.DingDingSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest; +import com.aliyun.dingtalkrobot_1_0.models.OrgGroupSendHeaders; +import com.aliyun.dingtalkrobot_1_0.models.OrgGroupSendRequest; +import com.aliyun.tea.TeaException; +import com.aliyun.teautil.Common; +import com.aliyun.teautil.models.RuntimeOptions; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class DingDingSinkConnector implements Sink { + + public static final Cache AUTH_CACHE = CacheBuilder.newBuilder() + .initialCapacity(12) + .maximumSize(10) + .concurrencyLevel(5) + .expireAfterWrite(20, TimeUnit.MINUTES) + .build(); + + public static final String ACCESS_TOKEN_CACHE_KEY = "access_token"; + + private DingDingSinkConfig sinkConfig; + + private com.aliyun.dingtalkrobot_1_0.Client sendMessageClient; + + private com.aliyun.dingtalkoauth2_1_0.Client authClient; + + private volatile boolean isRunning = false; + + @Override + public Class configClass() { + return DingDingSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for dingding sink connector + this.sinkConfig = (DingDingSinkConfig) config; + sendMessageClient = createSendMessageClient(); + authClient = createOAuthClient(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + // init config for dingding source connector + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (DingDingSinkConfig) sinkConnectorContext.getSinkConfig(); + sendMessageClient = createSendMessageClient(); + authClient = createOAuthClient(); + } + + @Override + public void start() { + isRunning = true; + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getSinkConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + isRunning = false; + } + + public boolean isRunning() { + return isRunning; + } + + @SneakyThrows + @Override + public void put(List sinkRecords) { + for (ConnectRecord record : sinkRecords) { + try { + if (Objects.isNull(record.getData())) { + log.warn("ConnectRecord data is null, ignore."); + continue; + } + String accessToken = getAccessToken(); + OrgGroupSendHeaders orgGroupSendHeaders = + new OrgGroupSendHeaders(); + orgGroupSendHeaders.xAcsDingtalkAccessToken = accessToken; + + String templateTypeKey = record.getExtension(ConnectRecordExtensionKeys.DINGTALK_TEMPLATE_TYPE); + if (null == templateTypeKey || "null".equals(templateTypeKey)) { + templateTypeKey = DingDingMessageTemplateType.PLAIN_TEXT.getTemplateType(); + } + DingDingMessageTemplateType templateType = DingDingMessageTemplateType.of(templateTypeKey); + + Map contentMap = new HashMap<>(); + if (DingDingMessageTemplateType.PLAIN_TEXT == templateType) { + contentMap.put("content", new String((byte[]) record.getData())); + } else if (DingDingMessageTemplateType.MARKDOWN == templateType) { + String title = Optional.ofNullable(record.getExtension(ConnectRecordExtensionKeys.DINGTALK_MARKDOWN_MESSAGE_TITLE)) + .orElse("EventMesh-Message"); + contentMap.put("title", title); + contentMap.put("text", new String((byte[]) record.getData())); + } + + OrgGroupSendRequest orgGroupSendRequest = + new OrgGroupSendRequest() + .setMsgParam(JsonUtils.toJSONString(contentMap)) + .setMsgKey(templateType.getTemplateKey()) + .setOpenConversationId(sinkConfig.getSinkConnectorConfig().getOpenConversationId()) + .setRobotCode(sinkConfig.getSinkConnectorConfig().getRobotCode()) + .setCoolAppCode(sinkConfig.getSinkConnectorConfig().getCoolAppCode()); + + try { + sendMessageClient.orgGroupSendWithOptions(orgGroupSendRequest, orgGroupSendHeaders, new RuntimeOptions()); + } catch (TeaException e) { + if (!Common.empty(e.code) && !Common.empty(e.message)) { + String errorMessage = e.getMessage(); + if ("invalidParameter.token.invalid".equals(errorMessage)) { + AUTH_CACHE.invalidate(ACCESS_TOKEN_CACHE_KEY); + } + } + } + } catch (Exception e) { + log.error("Failed to sink message to DingDing.", e); + } + } + } + + @SneakyThrows + private String getAccessToken() { + return AUTH_CACHE.get(ACCESS_TOKEN_CACHE_KEY, () -> { + GetAccessTokenRequest getAccessTokenRequest = + new GetAccessTokenRequest() + .setAppKey(sinkConfig.getSinkConnectorConfig().getAppKey()) + .setAppSecret(sinkConfig.getSinkConnectorConfig().getAppSecret()); + return authClient.getAccessToken(getAccessTokenRequest).getBody().getAccessToken(); + }); + } + + public static com.aliyun.dingtalkrobot_1_0.Client createSendMessageClient() throws Exception { + com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config(); + config.protocol = "https"; + config.regionId = "central"; + return new com.aliyun.dingtalkrobot_1_0.Client(config); + } + + public static com.aliyun.dingtalkoauth2_1_0.Client createOAuthClient() throws Exception { + com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config(); + config.protocol = "https"; + config.regionId = "central"; + return new com.aliyun.dingtalkoauth2_1_0.Client(config); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..551013beb6 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-DINGTALK + idc: FT + env: PRD + group: dingTalkSink + appId: 5034 + userName: dingTalkSinkUser + passWord: dingTalkPassWord +sinkConnectorConfig: + connectorName: dingTalkSink + appKey: dingTalkAppKey + appSecret: dingTalkAppSecret + openConversationId: dingTalkOpenConversationId + robotCode: dingTalkRobotCode diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/test/java/org/apache/eventmesh/connector/dingtalk/sink/connector/DingDingSinkConnectorTest.java b/eventmesh-connectors/eventmesh-connector-dingtalk/src/test/java/org/apache/eventmesh/connector/dingtalk/sink/connector/DingDingSinkConnectorTest.java new file mode 100644 index 0000000000..38a136748c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/test/java/org/apache/eventmesh/connector/dingtalk/sink/connector/DingDingSinkConnectorTest.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.connector.dingtalk.sink.connector; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.apache.eventmesh.connector.dingtalk.common.constants.ConnectRecordExtensionKeys; +import org.apache.eventmesh.connector.dingtalk.config.DingDingMessageTemplateType; +import org.apache.eventmesh.connector.dingtalk.sink.config.DingDingSinkConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ReflectionSupport; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse; +import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponseBody; + +@ExtendWith(MockitoExtension.class) +public class DingDingSinkConnectorTest { + + @Spy + private DingDingSinkConnector connector; + + @Mock + private com.aliyun.dingtalkrobot_1_0.Client sendMessageClient; + + @Mock + private com.aliyun.dingtalkoauth2_1_0.Client authClient; + + @BeforeEach + public void setUp() throws Exception { + Mockito.doReturn(null).when(sendMessageClient) + .orgGroupSendWithOptions(Mockito.any(), Mockito.any(), Mockito.any()); + GetAccessTokenResponse response = new GetAccessTokenResponse(); + GetAccessTokenResponseBody body = new GetAccessTokenResponseBody(); + body.setAccessToken("testAccessToken"); + response.setBody(body); + Mockito.doReturn(response).when(authClient).getAccessToken(Mockito.any()); + + DingDingSinkConfig sinkConfig = (DingDingSinkConfig) ConfigUtil.parse(connector.configClass()); + connector.init(sinkConfig); + Field sendMessageClientField = ReflectionSupport.findFields(connector.getClass(), + (f) -> f.getName().equals("sendMessageClient"), + HierarchyTraversalMode.BOTTOM_UP).get(0); + Field authClientField = ReflectionSupport.findFields(connector.getClass(), + (f) -> f.getName().equals("authClient"), + HierarchyTraversalMode.BOTTOM_UP).get(0); + sendMessageClientField.setAccessible(true); + authClientField.setAccessible(true); + sendMessageClientField.set(connector, sendMessageClient); + authClientField.set(connector, authClient); + connector.start(); + } + + @Test + public void testSendMessageToDingDing() throws Exception { + final int times = 3; + List records = new ArrayList<>(); + for (int i = 0; i < times; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, + System.currentTimeMillis(), "Hello, EventMesh!".getBytes(StandardCharsets.UTF_8)); + connectRecord.addExtension(ConnectRecordExtensionKeys.DINGTALK_TEMPLATE_TYPE, + DingDingMessageTemplateType.PLAIN_TEXT.getTemplateType()); + records.add(connectRecord); + } + connector.put(records); + verify(sendMessageClient, times(times)).orgGroupSendWithOptions(any(), any(), any()); + // verify for access token cache. + verify(authClient, times(1)).getAccessToken(any()); + } + + @AfterEach + public void tearDown() { + DingDingSinkConnector.AUTH_CACHE.invalidate(DingDingSinkConnector.ACCESS_TOKEN_CACHE_KEY); + connector.stop(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/test/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-dingtalk/src/test/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/test/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-dingtalk/src/test/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-dingtalk/src/test/resources/sink-config.yml new file mode 100644 index 0000000000..53f4a24da6 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-dingtalk/src/test/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-DINGDING + idc: FT + env: PRD + group: dingDingSink + appId: 5034 + userName: dingDingSinkUser + passWord: dingDingPassWord +sinkConnectorConfig: + connectorName: dingDingSink + appKey: dingDingAppKey + appSecret: dingDingAppSecret + openConversationId: dingDingOpenConversationId + robotCode: dingDingRobotCode \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-file/build.gradle b/eventmesh-connectors/eventmesh-connector-file/build.gradle new file mode 100644 index 0000000000..11eaa5b7e0 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/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 { + api project(":eventmesh-openconnect:eventmesh-openconnect-java") + testImplementation('org.junit.jupiter:junit-jupiter') + testImplementation('org.mockito:mockito-junit-jupiter') + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-file/gradle.properties b/eventmesh-connectors/eventmesh-connector-file/gradle.properties new file mode 100644 index 0000000000..1820ec46fa --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/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=file \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/config/FileServerConfig.java b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/config/FileServerConfig.java new file mode 100644 index 0000000000..b6b506521e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/config/FileServerConfig.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.file.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class FileServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; + +} diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/server/FileConnectServer.java b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/server/FileConnectServer.java new file mode 100644 index 0000000000..ac52432701 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/server/FileConnectServer.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.connector.file.server; + +import org.apache.eventmesh.connector.file.config.FileServerConfig; +import org.apache.eventmesh.connector.file.sink.connector.FileSinkConnector; +import org.apache.eventmesh.connector.file.source.connector.FileSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class FileConnectServer { + + public static void main(String[] args) throws Exception { + + FileServerConfig serverConfig = ConfigUtil.parse(FileServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application fileSourceApp = new Application(); + fileSourceApp.run(FileSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application fileSinkApp = new Application(); + fileSinkApp.run(FileSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/sink/config/FileSinkConfig.java b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/sink/config/FileSinkConfig.java new file mode 100644 index 0000000000..abdae52770 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/sink/config/FileSinkConfig.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.file.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class FileSinkConfig extends SinkConfig { + + public SinkConnectorConfig connectorConfig; + + private Integer flushSize = 1000; + + private boolean hourlyFlushEnabled = false; + +} diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..a8cf958f7f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/sink/config/SinkConnectorConfig.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.connector.file.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String topic; +} diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/sink/connector/FileSinkConnector.java b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/sink/connector/FileSinkConnector.java new file mode 100644 index 0000000000..f1d1ccc57b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/sink/connector/FileSinkConnector.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.connector.file.sink.connector; + +import org.apache.eventmesh.connector.file.sink.config.FileSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.time.LocalDateTime; +import java.util.Calendar; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.atomic.AtomicInteger; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class FileSinkConnector implements Sink { + + private static final AtomicInteger fileSize = new AtomicInteger(0); + + private String filePath; + + private String fileName; + + private int flushSize; + + private boolean hourlyFlushEnabled; + + private FileSinkConfig sinkConfig; + + private PrintStream outputStream; + + @Override + public Class configClass() { + return FileSinkConfig.class; + } + + @Override + public void init(Config config) { + // init config for hdfs source connector + this.sinkConfig = (FileSinkConfig) config; + this.filePath = buildFilePath(); + this.fileName = buildFileName(); + this.flushSize = sinkConfig.getFlushSize(); + this.hourlyFlushEnabled = sinkConfig.isHourlyFlushEnabled(); + } + + @Override + public void init(ConnectorContext connectorContext) { + // init config for hdfs source connector + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (FileSinkConfig) sinkConnectorContext.getSinkConfig(); + this.fileName = buildFileName(); + this.filePath = buildFilePath(); + this.flushSize = sinkConfig.getFlushSize(); + this.hourlyFlushEnabled = sinkConfig.isHourlyFlushEnabled(); + } + + @Override + public void start() throws Exception { + if (fileName == null || fileName.length() == 0 || filePath == null || filePath.length() == 0) { + this.outputStream = System.out; + } else { + this.outputStream = + new PrintStream(Files.newOutputStream(Paths.get(filePath + fileName), StandardOpenOption.CREATE, StandardOpenOption.APPEND), + false, StandardCharsets.UTF_8.name()); + } + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + outputStream.flush(); + outputStream.close(); + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + // the file data exceed the flushSize create the new file or + // hourlyFlushEnabled && time on the hour + if (fileSize.get() >= flushSize || (hourlyFlushEnabled && LocalDateTime.now().getHour() == 0)) { + log.info("flush the file and open"); + outputStream.flush(); + outputStream.close(); + try { + fileSize.set(0); + this.outputStream = openWithNewFile(); + } catch (IOException e) { + log.error("create file under path {} error", filePath); + throw new RuntimeException(e); + } + } + outputStream.println(new String((byte[]) connectRecord.getData(), StandardCharsets.UTF_8)); + fileSize.addAndGet(1); + } + } + + private String buildFilePath() { + Calendar calendar = Calendar.getInstance(Locale.CHINA); + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH) + 1; + int day = calendar.get(Calendar.DATE); + String filePath = sinkConfig.getConnectorConfig().getTopic() + + File.separator + year + File.separator + month + File.separator + day + File.separator; + File path = new File(filePath); + if (!path.exists()) { + if (!path.mkdirs()) { + log.error("make file dir {} error", filePath); + } + } + return filePath; + } + + private String buildFileName() { + Calendar calendar = Calendar.getInstance(Locale.CHINA); + long currentTime = calendar.getTime().getTime(); + return sinkConfig.getConnectorConfig().getTopic() + "-" + calendar.get(Calendar.HOUR_OF_DAY) + "-" + currentTime; + } + + private PrintStream openWithNewFile() throws IOException { + this.filePath = buildFilePath(); + this.fileName = buildFileName(); + if (fileName.length() == 0 || filePath == null || filePath.length() == 0) { + return System.out; + } + return new PrintStream(Files.newOutputStream(Paths.get(filePath + fileName), + StandardOpenOption.CREATE, StandardOpenOption.APPEND), + false, StandardCharsets.UTF_8.name()); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/source/config/FileSourceConfig.java b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/source/config/FileSourceConfig.java new file mode 100644 index 0000000000..b969544403 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/source/config/FileSourceConfig.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.file.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class FileSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..6376a7fb4a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/source/config/SourceConnectorConfig.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.connector.file.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private String filePath; +} diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/source/connector/FileSourceConnector.java b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/source/connector/FileSourceConnector.java new file mode 100644 index 0000000000..2b55284741 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/java/org/apache/eventmesh/connector/file/source/connector/FileSourceConnector.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.connector.file.source.connector; + +import org.apache.eventmesh.connector.file.source.config.FileSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class FileSourceConnector implements Source { + private static final int BUFFER_SIZE = 8192; + private FileSourceConfig sourceConfig; + private String filePath; + private String fileName; + private BufferedReader bufferedReader; + + @Override + public Class configClass() { + return FileSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for hdfs source connector + this.sourceConfig = (FileSourceConfig) config; + this.filePath = ((FileSourceConfig) config).getConnectorConfig().getFilePath(); + this.fileName = getFileName(filePath); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (FileSourceConfig) sourceConnectorContext.getSourceConfig(); + } + + @Override + public void start() throws Exception { + if (filePath == null || filePath.isEmpty()) { + this.bufferedReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); + } else { + Path path = Paths.get(filePath); + this.bufferedReader = new BufferedReader(new InputStreamReader(Files.newInputStream(path), StandardCharsets.UTF_8), BUFFER_SIZE); + } + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + try { + if (bufferedReader != null) { + bufferedReader.close(); + } + } catch (Exception e) { + log.error("Error closing resources: {}", e.getMessage()); + } + } + + @Override + public List poll() { + List connectRecords = new ArrayList<>(); + RecordPartition recordPartition = convertToRecordPartition(fileName); + try { + int bytesRead; + char[] buffer = new char[BUFFER_SIZE]; + while ((bytesRead = bufferedReader.read(buffer)) != -1) { + String line = new String(buffer, 0, bytesRead); + long timeStamp = System.currentTimeMillis(); + ConnectRecord connectRecord = new ConnectRecord(recordPartition, null, timeStamp, line); + connectRecords.add(connectRecord); + } + } catch (IOException e) { + log.error("Error reading data from the file: {}", e.getMessage()); + } + return connectRecords; + } + + public static RecordPartition convertToRecordPartition(String fileName) { + Map map = new HashMap<>(); + map.put("fileName", fileName); + return new RecordPartition(map); + } + + private static String getFileName(String filePath) throws NullPointerException { + File file = new File(filePath); + return file.getName(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-file/src/main/resources/server-config.yml new file mode 100644 index 0000000000..d9416e1ed2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: false +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-file/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..03789687ed --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: fileSink + appId: 5031 + userName: fileSinkUser + passWord: filePassWord +connectorConfig: + connectorName: fileSink + topic: TopicTest diff --git a/eventmesh-connectors/eventmesh-connector-file/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-file/src/main/resources/source-config.yml new file mode 100644 index 0000000000..9dd5dc0e56 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/main/resources/source-config.yml @@ -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. +# +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: fileSource + appId: 5032 + userName: fileSourceUser + passWord: filePassWord +connectorConfig: + connectorName: fileSource + filePath: userFilePath + diff --git a/eventmesh-connectors/eventmesh-connector-file/src/test/java/org/apache/eventmesh/connector/file/FileSourceConnectorTest.java b/eventmesh-connectors/eventmesh-connector-file/src/test/java/org/apache/eventmesh/connector/file/FileSourceConnectorTest.java new file mode 100644 index 0000000000..49421dd077 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-file/src/test/java/org/apache/eventmesh/connector/file/FileSourceConnectorTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.file; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.connector.file.source.config.FileSourceConfig; +import org.apache.eventmesh.connector.file.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.file.source.connector.FileSourceConnector; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +class FileSourceConnectorTest { + + private FileSourceConnector fileSourceConnector; + @Mock + private FileSourceConfig fileSourceConfig; + + @Test + void testFileSourceConnector() throws Exception { + String directoryPath = "d/g/"; + Path directory = Paths.get(directoryPath); + Files.createDirectories(directory); + Path newFilePath = directory.resolve("foo.txt"); + Files.createFile(newFilePath); + fileSourceConfig = mock(FileSourceConfig.class); + SourceConnectorConfig connectorConfig = mock(SourceConnectorConfig.class); + when(fileSourceConfig.getConnectorConfig()).thenReturn(connectorConfig); + when(fileSourceConfig.getConnectorConfig().getFilePath()).thenReturn("d/g/foo.txt"); + String filePath = fileSourceConfig.getConnectorConfig().getFilePath(); + Path mockPath = Paths.get(filePath); + String content = "line1\nline2\nline3"; + byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8); + Files.write(mockPath, contentBytes); + fileSourceConnector = new FileSourceConnector(); + fileSourceConnector.init(fileSourceConfig); + fileSourceConnector.start(); + List connectRecords = fileSourceConnector.poll(); + fileSourceConnector.stop(); + Files.delete(newFilePath); + Assertions.assertEquals(content, connectRecords.get(0).getData().toString()); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-http/build.gradle b/eventmesh-connectors/eventmesh-connector-http/build.gradle new file mode 100644 index 0000000000..734b2fc622 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/build.gradle @@ -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. + */ + +dependencies { + api project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation project(":eventmesh-common") + implementation 'io.cloudevents:cloudevents-http-vertx:2.3.0' + implementation 'io.vertx:vertx-web:4.4.6' + + testImplementation "org.apache.httpcomponents:httpclient" + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-http/gradle.properties b/eventmesh-connectors/eventmesh-connector-http/gradle.properties new file mode 100644 index 0000000000..cc0e7324ca --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-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=connector +pluginName=http \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/config/HttpServerConfig.java b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/config/HttpServerConfig.java new file mode 100644 index 0000000000..81a9f20923 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/config/HttpServerConfig.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.http.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class HttpServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/server/HttpConnectServer.java b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/server/HttpConnectServer.java new file mode 100644 index 0000000000..bd94fed126 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/server/HttpConnectServer.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.connector.http.server; + +import org.apache.eventmesh.connector.http.config.HttpServerConfig; +import org.apache.eventmesh.connector.http.source.connector.HttpSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +public class HttpConnectServer { + + public static void main(String[] args) throws Exception { + HttpServerConfig serverConfig = ConfigUtil.parse(HttpServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application httpSourceApp = new Application(); + httpSourceApp.run(HttpSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + // TODO support sink connector + } + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/source/config/HttpSourceConfig.java b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/source/config/HttpSourceConfig.java new file mode 100644 index 0000000000..bee870cb1a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/source/config/HttpSourceConfig.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.http.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class HttpSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..873a0d1922 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/source/config/SourceConnectorConfig.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.http.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private String path; + + private int port; + + private int idleTimeout; +} diff --git a/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/source/connector/HttpSourceConnector.java b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/source/connector/HttpSourceConnector.java new file mode 100644 index 0000000000..f9a6c568e0 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/main/java/org/apache/eventmesh/connector/http/source/connector/HttpSourceConnector.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.http.source.connector; + +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.connector.http.source.config.HttpSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import io.cloudevents.CloudEvent; +import io.cloudevents.http.vertx.VertxMessageFactory; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.vertx.core.Vertx; +import io.vertx.core.http.HttpMethod; +import io.vertx.core.http.HttpServer; +import io.vertx.core.http.HttpServerOptions; +import io.vertx.ext.web.Router; +import io.vertx.ext.web.handler.LoggerHandler; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HttpSourceConnector implements Source { + + private static final int DEFAULT_BATCH_SIZE = 10; + + private HttpSourceConfig sourceConfig; + private BlockingQueue queue; + private HttpServer server; + + @Override + public Class configClass() { + return HttpSourceConfig.class; + } + + @Override + public void init(Config config) { + this.sourceConfig = (HttpSourceConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (HttpSourceConfig) sourceConnectorContext.getSourceConfig(); + doInit(); + } + + private void doInit() { + this.queue = new LinkedBlockingQueue<>(1000); + + final Vertx vertx = Vertx.vertx(); + final Router router = Router.router(vertx); + router.route() + .path(this.sourceConfig.connectorConfig.getPath()) + .method(HttpMethod.POST) + .handler(LoggerHandler.create()) + .handler(ctx -> { + VertxMessageFactory.createReader(ctx.request()) + .map(reader -> { + CloudEvent event = reader.toEvent(); + if (event.getSubject() == null) { + throw new IllegalStateException("attribute 'subject' cannot be null"); + } + if (event.getDataContentType() == null) { + throw new IllegalStateException("attribute 'datacontenttype' cannot be null"); + } + if (event.getData() == null) { + throw new IllegalStateException("attribute 'data' cannot be null"); + } + return event; + }) + .onSuccess(event -> { + queue.add(event); + log.info("[HttpSourceConnector] Succeed to convert payload into CloudEvent. StatusCode={}", HttpResponseStatus.OK.code()); + ctx.response().setStatusCode(HttpResponseStatus.OK.code()).end(); + }) + .onFailure(t -> { + log.error("[HttpSourceConnector] Malformed request. StatusCode={}", HttpResponseStatus.BAD_REQUEST.code(), t); + ctx.response().setStatusCode(HttpResponseStatus.BAD_REQUEST.code()).end(); + }); + }); + this.server = vertx.createHttpServer(new HttpServerOptions() + .setPort(this.sourceConfig.connectorConfig.getPort()) + .setIdleTimeout(this.sourceConfig.connectorConfig.getIdleTimeout())).requestHandler(router); + } + + @Override + public void start() { + Throwable t = this.server.listen().cause(); + if (t != null) { + throw new EventMeshException("failed to start Vertx server", t); + } + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + Throwable t = this.server.close().cause(); + if (t != null) { + throw new EventMeshException("failed to stop Vertx server", t); + } + } + + @Override + public List poll() { + List connectRecords = new ArrayList<>(DEFAULT_BATCH_SIZE); + for (int i = 0; i < DEFAULT_BATCH_SIZE; i++) { + try { + CloudEvent event = queue.poll(3, TimeUnit.SECONDS); + if (event == null) { + break; + } + connectRecords.add(CloudEventUtil.convertEventToRecord(event)); + } catch (InterruptedException e) { + break; + } + } + return connectRecords; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-http/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-http/src/main/resources/server-config.yml new file mode 100644 index 0000000000..0cd7b5b5ab --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: false diff --git a/eventmesh-connectors/eventmesh-connector-http/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-http/src/main/resources/source-config.yml new file mode 100644 index 0000000000..9fcc471d3b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: httpSource + appId: 5032 + userName: httpSourceUser + passWord: httpPassWord +connectorConfig: + connectorName: httpSource + path: /test + port: 3755 + idleTimeout: 5 \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-http/src/test/java/org/apache/eventmesh/connector/http/source/connector/HttpSourceConnectorTest.java b/eventmesh-connectors/eventmesh-connector-http/src/test/java/org/apache/eventmesh/connector/http/source/connector/HttpSourceConnectorTest.java new file mode 100644 index 0000000000..35d58b75c1 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/test/java/org/apache/eventmesh/connector/http/source/connector/HttpSourceConnectorTest.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.http.source.connector; + +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.connector.http.source.config.HttpSourceConfig; +import org.apache.eventmesh.connector.http.source.config.SourceConnectorConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import org.apache.http.HttpHeaders; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class HttpSourceConnectorTest { + + private HttpSourceConnector connector; + private SourceConnectorConfig config; + private CloseableHttpClient httpClient; + private String uri; + private final String expectedMessage = "testHttpMessage"; + + @BeforeEach + void setUp() throws Exception { + connector = new HttpSourceConnector(); + HttpSourceConfig sourceConfig = (HttpSourceConfig) ConfigUtil.parse(connector.configClass()); + config = sourceConfig.getConnectorConfig(); + connector.init(sourceConfig); + connector.start(); + + uri = new URIBuilder().setScheme("http").setHost("127.0.0.1").setPort(config.getPort()).setPath(config.getPath()).build().toString(); + + httpClient = HttpClients.createDefault(); + } + + @Test + void testPoll() throws Exception { + final int batchSize = 10; + // test binary content mode + for (int i = 0; i < batchSize; i++) { + HttpResponse resp = mockBinaryRequest(); + Assertions.assertEquals(resp.getStatusLine().getStatusCode(), HttpStatus.SC_OK); + + } + List res = connector.poll(); + Assertions.assertEquals(batchSize, res.size()); + for (ConnectRecord r : res) { + Assertions.assertEquals(expectedMessage, new String((byte[]) r.getData())); + } + + // test structured content mode + for (int i = 0; i < batchSize; i++) { + HttpResponse resp = mockStructuredRequest(); + Assertions.assertEquals(resp.getStatusLine().getStatusCode(), HttpStatus.SC_OK); + } + res = connector.poll(); + Assertions.assertEquals(batchSize, res.size()); + for (ConnectRecord r : res) { + Assertions.assertEquals(expectedMessage, new String((byte[]) r.getData())); + } + + // test invalid requests + HttpPost invalidPost = new HttpPost(uri); + invalidPost.setHeader(HttpHeaders.CONTENT_TYPE, "text/plain"); + invalidPost.setHeader("ce-id", String.valueOf(UUID.randomUUID())); + HttpResponse resp = httpClient.execute(invalidPost); + Assertions.assertEquals(HttpStatus.SC_BAD_REQUEST, resp.getStatusLine().getStatusCode()); + } + + HttpResponse mockBinaryRequest() throws Exception { + HttpPost httpPost = new HttpPost(uri); + httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "text/plain"); + httpPost.setHeader("ce-id", String.valueOf(UUID.randomUUID())); + httpPost.setHeader("ce-specversion", "1.0"); + httpPost.setHeader("ce-type", "com.example.someevent"); + httpPost.setHeader("ce-source", "/mycontext"); + httpPost.setHeader("ce-subject", "test"); + httpPost.setEntity(new StringEntity(expectedMessage)); + + return httpClient.execute(httpPost); + } + + HttpResponse mockStructuredRequest() throws Exception { + HttpPost httpPost = new HttpPost(uri); + // according to the CloudEvent specification, a json format event MUST use the media type `application/cloudevents+json` + httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/cloudevents+json"); + TestEvent event = new TestEvent(); + event.id = String.valueOf(UUID.randomUUID()); + event.specversion = "1.0"; + event.type = "com.example.someevent"; + event.source = "/mycontext"; + event.subject = "test"; + event.datacontenttype = "text/plain"; + event.data = expectedMessage; + httpPost.setEntity(new StringEntity(JsonUtils.toJSONString(event))); + + return httpClient.execute(httpPost); + } + + @AfterEach + void tearDown() throws Exception { + connector.stop(); + httpClient.close(); + } + + class TestEvent { + + public String specversion; + public String type; + public String source; + public String subject; + public String datacontenttype; + public String id; + + public String data; + } +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-http/src/test/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-http/src/test/resources/server-config.yml new file mode 100644 index 0000000000..0cd7b5b5ab --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/test/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: false diff --git a/eventmesh-connectors/eventmesh-connector-http/src/test/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-http/src/test/resources/source-config.yml new file mode 100644 index 0000000000..0a3e68d070 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-http/src/test/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: httpSource + appId: 5032 + userName: httpSourceUser + passWord: httpmqPassWord +connectorConfig: + connectorName: httpSource + path: /test + port: 3755 \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/build.gradle b/eventmesh-connectors/eventmesh-connector-jdbc/build.gradle new file mode 100644 index 0000000000..b6d33aebe3 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/build.gradle @@ -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. + */ + +plugins { + id 'antlr' +} + +repositories { + mavenCentral() +} + +generateGrammarSource { + maxHeapSize = '64m' + arguments += ['-package', 'org.apache.eventmesh.connector.jdbc.antlr4.autogeneration', '-visitor'] + outputDirectory = file('src/main/java/org/apache/eventmesh/connector/jdbc/antlr4/autogeneration') +} + +packageSources { + dependsOn generateGrammarSource +} + +dependencies { + antlr("org.antlr:antlr4:4.13.0") + implementation 'org.antlr:antlr4-runtime:4.13.0' + implementation project(":eventmesh-common") + implementation project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation project(":eventmesh-spi") + implementation 'com.zendesk:mysql-binlog-connector-java:0.28.0' + implementation 'mysql:mysql-connector-java:8.0.32' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation "org.assertj:assertj-core" + + testImplementation "org.mockito:mockito-core" +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/gradle.properties b/eventmesh-connectors/eventmesh-connector-jdbc/gradle.properties new file mode 100644 index 0000000000..e230cab2e4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/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=jdbc \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/antlr/MySqlLexer.g4 b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/antlr/MySqlLexer.g4 new file mode 100644 index 0000000000..6ecef13c3e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/antlr/MySqlLexer.g4 @@ -0,0 +1,1356 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +lexer grammar MySqlLexer; + +options { caseInsensitive = true; } + +channels { MYSQLCOMMENT, ERRORCHANNEL } + +// SKIP + +SPACE: [ \t\r\n]+ -> channel(HIDDEN); +SPEC_MYSQL_COMMENT: '/*!' .+? '*/' -> channel(MYSQLCOMMENT); +COMMENT_INPUT: '/*' .*? '*/' -> channel(HIDDEN); +LINE_COMMENT: ( + ('--' [ \t]* | '#') ~[\r\n]* ('\r'? '\n' | EOF) + | '--' ('\r'? '\n' | EOF) + ) -> channel(HIDDEN); + + +// Keywords +// Common Keywords + +ADD: 'ADD'; +ALL: 'ALL'; +ALTER: 'ALTER'; +ALWAYS: 'ALWAYS'; +ANALYZE: 'ANALYZE'; +AND: 'AND'; +ARRAY: 'ARRAY'; +AS: 'AS'; +ASC: 'ASC'; +ATTRIBUTE: 'ATTRIBUTE'; +BEFORE: 'BEFORE'; +BETWEEN: 'BETWEEN'; +BOTH: 'BOTH'; +BUCKETS: 'BUCKETS'; +BY: 'BY'; +CALL: 'CALL'; +CASCADE: 'CASCADE'; +CASE: 'CASE'; +CAST: 'CAST'; +CHANGE: 'CHANGE'; +CHARACTER: 'CHARACTER'; +CHECK: 'CHECK'; +COLLATE: 'COLLATE'; +COLUMN: 'COLUMN'; +CONDITION: 'CONDITION'; +CONSTRAINT: 'CONSTRAINT'; +CONTINUE: 'CONTINUE'; +CONVERT: 'CONVERT'; +CREATE: 'CREATE'; +CROSS: 'CROSS'; +CURRENT: 'CURRENT'; +CURRENT_ROLE: 'CURRENT_ROLE'; +CURRENT_USER: 'CURRENT_USER'; +CURSOR: 'CURSOR'; +DATABASE: 'DATABASE'; +DATABASES: 'DATABASES'; +DECLARE: 'DECLARE'; +DEFAULT: 'DEFAULT'; +DELAYED: 'DELAYED'; +DELETE: 'DELETE'; +DESC: 'DESC'; +DESCRIBE: 'DESCRIBE'; +DETERMINISTIC: 'DETERMINISTIC'; +DIAGNOSTICS: 'DIAGNOSTICS'; +DISTINCT: 'DISTINCT'; +DISTINCTROW: 'DISTINCTROW'; +DROP: 'DROP'; +EACH: 'EACH'; +ELSE: 'ELSE'; +ELSEIF: 'ELSEIF'; +EMPTY: 'EMPTY'; +ENCLOSED: 'ENCLOSED'; +ENFORCED: 'ENFORCED'; +ESCAPED: 'ESCAPED'; +EXCEPT: 'EXCEPT'; +EXISTS: 'EXISTS'; +EXIT: 'EXIT'; +EXPLAIN: 'EXPLAIN'; +FALSE: 'FALSE'; +FETCH: 'FETCH'; +FOR: 'FOR'; +FORCE: 'FORCE'; +FOREIGN: 'FOREIGN'; +FROM: 'FROM'; +FULLTEXT: 'FULLTEXT'; +GENERATED: 'GENERATED'; +GET: 'GET'; +GRANT: 'GRANT'; +GROUP: 'GROUP'; +HAVING: 'HAVING'; +HIGH_PRIORITY: 'HIGH_PRIORITY'; +HISTOGRAM: 'HISTOGRAM'; +IF: 'IF'; +IGNORE: 'IGNORE'; +IGNORED: 'IGNORED'; +IN: 'IN'; +INDEX: 'INDEX'; +INFILE: 'INFILE'; +INNER: 'INNER'; +INOUT: 'INOUT'; +INSERT: 'INSERT'; +INTERVAL: 'INTERVAL'; +INTO: 'INTO'; +IS: 'IS'; +ITERATE: 'ITERATE'; +JOIN: 'JOIN'; +KEY: 'KEY'; +KEYS: 'KEYS'; +KILL: 'KILL'; +LATERAL: 'LATERAL'; +LEADING: 'LEADING'; +LEAVE: 'LEAVE'; +LEFT: 'LEFT'; +LIKE: 'LIKE'; +LIMIT: 'LIMIT'; +LINEAR: 'LINEAR'; +LINES: 'LINES'; +LOAD: 'LOAD'; +LOCK: 'LOCK'; +LOCKED: 'LOCKED'; +LOOP: 'LOOP'; +LOW_PRIORITY: 'LOW_PRIORITY'; +MASTER_BIND: 'MASTER_BIND'; +MASTER_SSL_VERIFY_SERVER_CERT: 'MASTER_SSL_VERIFY_SERVER_CERT'; +MATCH: 'MATCH'; +MAXVALUE: 'MAXVALUE'; +MINVALUE: 'MINVALUE'; +MODIFIES: 'MODIFIES'; +NATURAL: 'NATURAL'; +NOT: 'NOT'; +NO_WRITE_TO_BINLOG: 'NO_WRITE_TO_BINLOG'; +NULL_LITERAL: 'NULL'; +NUMBER: 'NUMBER'; +ON: 'ON'; +OPTIMIZE: 'OPTIMIZE'; +OPTION: 'OPTION'; +OPTIONAL: 'OPTIONAL'; +OPTIONALLY: 'OPTIONALLY'; +OR: 'OR'; +ORDER: 'ORDER'; +OUT: 'OUT'; +OUTER: 'OUTER'; +OUTFILE: 'OUTFILE'; +OVER: 'OVER'; +PARTITION: 'PARTITION'; +PRIMARY: 'PRIMARY'; +PROCEDURE: 'PROCEDURE'; +PURGE: 'PURGE'; +RANGE: 'RANGE'; +READ: 'READ'; +READS: 'READS'; +REFERENCES: 'REFERENCES'; +REGEXP: 'REGEXP'; +RELEASE: 'RELEASE'; +RENAME: 'RENAME'; +REPEAT: 'REPEAT'; +REPLACE: 'REPLACE'; +REQUIRE: 'REQUIRE'; +RESIGNAL: 'RESIGNAL'; +RESTRICT: 'RESTRICT'; +RETAIN: 'RETAIN'; +RETURN: 'RETURN'; +REVOKE: 'REVOKE'; +RIGHT: 'RIGHT'; +RLIKE: 'RLIKE'; +SCHEMA: 'SCHEMA'; +SCHEMAS: 'SCHEMAS'; +SELECT: 'SELECT'; +SET: 'SET'; +SEPARATOR: 'SEPARATOR'; +SHOW: 'SHOW'; +SIGNAL: 'SIGNAL'; +SKIP_: 'SKIP'; +SKIP_QUERY_REWRITE: 'SKIP_QUERY_REWRITE'; +SPATIAL: 'SPATIAL'; +SQL: 'SQL'; +SQLEXCEPTION: 'SQLEXCEPTION'; +SQLSTATE: 'SQLSTATE'; +SQLWARNING: 'SQLWARNING'; +SQL_BIG_RESULT: 'SQL_BIG_RESULT'; +SQL_CALC_FOUND_ROWS: 'SQL_CALC_FOUND_ROWS'; +SQL_SMALL_RESULT: 'SQL_SMALL_RESULT'; +SSL: 'SSL'; +STACKED: 'STACKED'; +STARTING: 'STARTING'; +STATEMENT: 'STATEMENT'; +STRAIGHT_JOIN: 'STRAIGHT_JOIN'; +TABLE: 'TABLE'; +TERMINATED: 'TERMINATED'; +THEN: 'THEN'; +TO: 'TO'; +TRAILING: 'TRAILING'; +TRIGGER: 'TRIGGER'; +TRUE: 'TRUE'; +UNDO: 'UNDO'; +UNION: 'UNION'; +UNIQUE: 'UNIQUE'; +UNLOCK: 'UNLOCK'; +UNSIGNED: 'UNSIGNED'; +UPDATE: 'UPDATE'; +USAGE: 'USAGE'; +USE: 'USE'; +USING: 'USING'; +VALUES: 'VALUES'; +WHEN: 'WHEN'; +WHERE: 'WHERE'; +WHILE: 'WHILE'; +WITH: 'WITH'; +WRITE: 'WRITE'; +XOR: 'XOR'; +ZEROFILL: 'ZEROFILL'; + +// DATA TYPE Keywords + +TINYINT: 'TINYINT'; +SMALLINT: 'SMALLINT'; +MEDIUMINT: 'MEDIUMINT'; +MIDDLEINT: 'MIDDLEINT'; +INT: 'INT'; +INT1: 'INT1'; +INT2: 'INT2'; +INT3: 'INT3'; +INT4: 'INT4'; +INT8: 'INT8'; +INTEGER: 'INTEGER'; +BIGINT: 'BIGINT'; +REAL: 'REAL'; +DOUBLE: 'DOUBLE'; +PRECISION: 'PRECISION'; +FLOAT: 'FLOAT'; +FLOAT4: 'FLOAT4'; +FLOAT8: 'FLOAT8'; +DECIMAL: 'DECIMAL'; +DEC: 'DEC'; +NUMERIC: 'NUMERIC'; +DATE: 'DATE'; +TIME: 'TIME'; +TIMESTAMP: 'TIMESTAMP'; +DATETIME: 'DATETIME'; +YEAR: 'YEAR'; +CHAR: 'CHAR'; +VARCHAR: 'VARCHAR'; +NVARCHAR: 'NVARCHAR'; +NATIONAL: 'NATIONAL'; +BINARY: 'BINARY'; +VARBINARY: 'VARBINARY'; +TINYBLOB: 'TINYBLOB'; +BLOB: 'BLOB'; +MEDIUMBLOB: 'MEDIUMBLOB'; +LONG: 'LONG'; +LONGBLOB: 'LONGBLOB'; +TINYTEXT: 'TINYTEXT'; +TEXT: 'TEXT'; +MEDIUMTEXT: 'MEDIUMTEXT'; +LONGTEXT: 'LONGTEXT'; +ENUM: 'ENUM'; +VARYING: 'VARYING'; +SERIAL: 'SERIAL'; + + +// Interval type Keywords + +YEAR_MONTH: 'YEAR_MONTH'; +DAY_HOUR: 'DAY_HOUR'; +DAY_MINUTE: 'DAY_MINUTE'; +DAY_SECOND: 'DAY_SECOND'; +HOUR_MINUTE: 'HOUR_MINUTE'; +HOUR_SECOND: 'HOUR_SECOND'; +MINUTE_SECOND: 'MINUTE_SECOND'; +SECOND_MICROSECOND: 'SECOND_MICROSECOND'; +MINUTE_MICROSECOND: 'MINUTE_MICROSECOND'; +HOUR_MICROSECOND: 'HOUR_MICROSECOND'; +DAY_MICROSECOND: 'DAY_MICROSECOND'; + +// JSON keywords +JSON_ARRAY: 'JSON_ARRAY'; +JSON_ARRAYAGG: 'JSON_ARRAYAGG'; +JSON_ARRAY_APPEND: 'JSON_ARRAY_APPEND'; +JSON_ARRAY_INSERT: 'JSON_ARRAY_INSERT'; +JSON_CONTAINS: 'JSON_CONTAINS'; +JSON_CONTAINS_PATH: 'JSON_CONTAINS_PATH'; +JSON_DEPTH: 'JSON_DEPTH'; +JSON_EXTRACT: 'JSON_EXTRACT'; +JSON_INSERT: 'JSON_INSERT'; +JSON_KEYS: 'JSON_KEYS'; +JSON_LENGTH: 'JSON_LENGTH'; +JSON_MERGE: 'JSON_MERGE'; +JSON_MERGE_PATCH: 'JSON_MERGE_PATCH'; +JSON_MERGE_PRESERVE: 'JSON_MERGE_PRESERVE'; +JSON_OBJECT: 'JSON_OBJECT'; +JSON_OBJECTAGG: 'JSON_OBJECTAGG'; +JSON_OVERLAPS: 'JSON_OVERLAPS'; +JSON_PRETTY: 'JSON_PRETTY'; +JSON_QUOTE: 'JSON_QUOTE'; +JSON_REMOVE: 'JSON_REMOVE'; +JSON_REPLACE: 'JSON_REPLACE'; +JSON_SCHEMA_VALID: 'JSON_SCHEMA_VALID'; +JSON_SCHEMA_VALIDATION_REPORT: 'JSON_SCHEMA_VALIDATION_REPORT'; +JSON_SEARCH: 'JSON_SEARCH'; +JSON_SET: 'JSON_SET'; +JSON_STORAGE_FREE: 'JSON_STORAGE_FREE'; +JSON_STORAGE_SIZE: 'JSON_STORAGE_SIZE'; +JSON_TABLE: 'JSON_TABLE'; +JSON_TYPE: 'JSON_TYPE'; +JSON_UNQUOTE: 'JSON_UNQUOTE'; +JSON_VALID: 'JSON_VALID'; +JSON_VALUE: 'JSON_VALUE'; +NESTED: 'NESTED'; +ORDINALITY: 'ORDINALITY'; +PATH: 'PATH'; + +// Group function Keywords + +AVG: 'AVG'; +BIT_AND: 'BIT_AND'; +BIT_OR: 'BIT_OR'; +BIT_XOR: 'BIT_XOR'; +COUNT: 'COUNT'; +CUME_DIST: 'CUME_DIST'; +DENSE_RANK: 'DENSE_RANK'; +FIRST_VALUE: 'FIRST_VALUE'; +GROUP_CONCAT: 'GROUP_CONCAT'; +LAG: 'LAG'; +LAST_VALUE: 'LAST_VALUE'; +LEAD: 'LEAD'; +MAX: 'MAX'; +MIN: 'MIN'; +NTILE: 'NTILE'; +NTH_VALUE: 'NTH_VALUE'; +PERCENT_RANK: 'PERCENT_RANK'; +RANK: 'RANK'; +ROW_NUMBER: 'ROW_NUMBER'; +STD: 'STD'; +STDDEV: 'STDDEV'; +STDDEV_POP: 'STDDEV_POP'; +STDDEV_SAMP: 'STDDEV_SAMP'; +SUM: 'SUM'; +VAR_POP: 'VAR_POP'; +VAR_SAMP: 'VAR_SAMP'; +VARIANCE: 'VARIANCE'; + +// Common function Keywords + +CURRENT_DATE: 'CURRENT_DATE'; +CURRENT_TIME: 'CURRENT_TIME'; +CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'; +LOCALTIME: 'LOCALTIME'; +CURDATE: 'CURDATE'; +CURTIME: 'CURTIME'; +DATE_ADD: 'DATE_ADD'; +DATE_SUB: 'DATE_SUB'; +EXTRACT: 'EXTRACT'; +LOCALTIMESTAMP: 'LOCALTIMESTAMP'; +NOW: 'NOW'; +POSITION: 'POSITION'; +SUBSTR: 'SUBSTR'; +SUBSTRING: 'SUBSTRING'; +SYSDATE: 'SYSDATE'; +TRIM: 'TRIM'; +UTC_DATE: 'UTC_DATE'; +UTC_TIME: 'UTC_TIME'; +UTC_TIMESTAMP: 'UTC_TIMESTAMP'; + +// Keywords, but can be ID +// Common Keywords, but can be ID + +ACCOUNT: 'ACCOUNT'; +ACTION: 'ACTION'; +AFTER: 'AFTER'; +AGGREGATE: 'AGGREGATE'; +ALGORITHM: 'ALGORITHM'; +ANY: 'ANY'; +AT: 'AT'; +AUTHORS: 'AUTHORS'; +AUTOCOMMIT: 'AUTOCOMMIT'; +AUTOEXTEND_SIZE: 'AUTOEXTEND_SIZE'; +AUTO_INCREMENT: 'AUTO_INCREMENT'; +AVG_ROW_LENGTH: 'AVG_ROW_LENGTH'; +BEGIN: 'BEGIN'; +BINLOG: 'BINLOG'; +BIT: 'BIT'; +BLOCK: 'BLOCK'; +BOOL: 'BOOL'; +BOOLEAN: 'BOOLEAN'; +BTREE: 'BTREE'; +CACHE: 'CACHE'; +CASCADED: 'CASCADED'; +CHAIN: 'CHAIN'; +CHANGED: 'CHANGED'; +CHANNEL: 'CHANNEL'; +CHECKSUM: 'CHECKSUM'; +PAGE_CHECKSUM: 'PAGE_CHECKSUM'; +CIPHER: 'CIPHER'; +CLASS_ORIGIN: 'CLASS_ORIGIN'; +CLIENT: 'CLIENT'; +CLOSE: 'CLOSE'; +CLUSTERING: 'CLUSTERING'; +COALESCE: 'COALESCE'; +CODE: 'CODE'; +COLUMNS: 'COLUMNS'; +COLUMN_FORMAT: 'COLUMN_FORMAT'; +COLUMN_NAME: 'COLUMN_NAME'; +COMMENT: 'COMMENT'; +COMMIT: 'COMMIT'; +COMPACT: 'COMPACT'; +COMPLETION: 'COMPLETION'; +COMPRESSED: 'COMPRESSED'; +COMPRESSION: 'COMPRESSION' | QUOTE_SYMB? 'COMPRESSION' QUOTE_SYMB?; +CONCURRENT: 'CONCURRENT'; +CONNECT: 'CONNECT'; +CONNECTION: 'CONNECTION'; +CONSISTENT: 'CONSISTENT'; +CONSTRAINT_CATALOG: 'CONSTRAINT_CATALOG'; +CONSTRAINT_SCHEMA: 'CONSTRAINT_SCHEMA'; +CONSTRAINT_NAME: 'CONSTRAINT_NAME'; +CONTAINS: 'CONTAINS'; +CONTEXT: 'CONTEXT'; +CONTRIBUTORS: 'CONTRIBUTORS'; +COPY: 'COPY'; +CPU: 'CPU'; +CYCLE: 'CYCLE'; +CURSOR_NAME: 'CURSOR_NAME'; +DATA: 'DATA'; +DATAFILE: 'DATAFILE'; +DEALLOCATE: 'DEALLOCATE'; +DEFAULT_AUTH: 'DEFAULT_AUTH'; +DEFINER: 'DEFINER'; +DELAY_KEY_WRITE: 'DELAY_KEY_WRITE'; +DES_KEY_FILE: 'DES_KEY_FILE'; +DIRECTORY: 'DIRECTORY'; +DISABLE: 'DISABLE'; +DISCARD: 'DISCARD'; +DISK: 'DISK'; +DO: 'DO'; +DUMPFILE: 'DUMPFILE'; +DUPLICATE: 'DUPLICATE'; +DYNAMIC: 'DYNAMIC'; +ENABLE: 'ENABLE'; +ENCRYPTED: 'ENCRYPTED'; +ENCRYPTION: 'ENCRYPTION'; +ENCRYPTION_KEY_ID: 'ENCRYPTION_KEY_ID'; +END: 'END'; +ENDS: 'ENDS'; +ENGINE: 'ENGINE'; +ENGINES: 'ENGINES'; +ERROR: 'ERROR'; +ERRORS: 'ERRORS'; +ESCAPE: 'ESCAPE'; +EVEN: 'EVEN'; +EVENT: 'EVENT'; +EVENTS: 'EVENTS'; +EVERY: 'EVERY'; +EXCHANGE: 'EXCHANGE'; +EXCLUSIVE: 'EXCLUSIVE'; +EXPIRE: 'EXPIRE'; +EXPORT: 'EXPORT'; +EXTENDED: 'EXTENDED'; +EXTENT_SIZE: 'EXTENT_SIZE'; +FAILED_LOGIN_ATTEMPTS: 'FAILED_LOGIN_ATTEMPTS'; +FAST: 'FAST'; +FAULTS: 'FAULTS'; +FIELDS: 'FIELDS'; +FILE_BLOCK_SIZE: 'FILE_BLOCK_SIZE'; +FILTER: 'FILTER'; +FIRST: 'FIRST'; +FIXED: 'FIXED'; +FLUSH: 'FLUSH'; +FOLLOWING: 'FOLLOWING'; +FOLLOWS: 'FOLLOWS'; +FOUND: 'FOUND'; +FULL: 'FULL'; +FUNCTION: 'FUNCTION'; +GENERAL: 'GENERAL'; +GLOBAL: 'GLOBAL'; +GRANTS: 'GRANTS'; +GROUP_REPLICATION: 'GROUP_REPLICATION'; +HANDLER: 'HANDLER'; +HASH: 'HASH'; +HELP: 'HELP'; +HISTORY: 'HISTORY'; +HOST: 'HOST'; +HOSTS: 'HOSTS'; +IDENTIFIED: 'IDENTIFIED'; +IGNORE_SERVER_IDS: 'IGNORE_SERVER_IDS'; +IMPORT: 'IMPORT'; +INCREMENT: 'INCREMENT'; +INDEXES: 'INDEXES'; +INITIAL_SIZE: 'INITIAL_SIZE'; +INPLACE: 'INPLACE'; +INSERT_METHOD: 'INSERT_METHOD'; +INSTALL: 'INSTALL'; +INSTANCE: 'INSTANCE'; +INSTANT: 'INSTANT'; +INVISIBLE: 'INVISIBLE'; +INVOKER: 'INVOKER'; +IO: 'IO'; +IO_THREAD: 'IO_THREAD'; +IPC: 'IPC'; +ISOLATION: 'ISOLATION'; +ISSUER: 'ISSUER'; +JSON: 'JSON'; +KEY_BLOCK_SIZE: 'KEY_BLOCK_SIZE'; +LANGUAGE: 'LANGUAGE'; +LAST: 'LAST'; +LEAVES: 'LEAVES'; +LESS: 'LESS'; +LEVEL: 'LEVEL'; +LIST: 'LIST'; +LOCAL: 'LOCAL'; +LOGFILE: 'LOGFILE'; +LOGS: 'LOGS'; +MASTER: 'MASTER'; +MASTER_AUTO_POSITION: 'MASTER_AUTO_POSITION'; +MASTER_CONNECT_RETRY: 'MASTER_CONNECT_RETRY'; +MASTER_DELAY: 'MASTER_DELAY'; +MASTER_HEARTBEAT_PERIOD: 'MASTER_HEARTBEAT_PERIOD'; +MASTER_HOST: 'MASTER_HOST'; +MASTER_LOG_FILE: 'MASTER_LOG_FILE'; +MASTER_LOG_POS: 'MASTER_LOG_POS'; +MASTER_PASSWORD: 'MASTER_PASSWORD'; +MASTER_PORT: 'MASTER_PORT'; +MASTER_RETRY_COUNT: 'MASTER_RETRY_COUNT'; +MASTER_SSL: 'MASTER_SSL'; +MASTER_SSL_CA: 'MASTER_SSL_CA'; +MASTER_SSL_CAPATH: 'MASTER_SSL_CAPATH'; +MASTER_SSL_CERT: 'MASTER_SSL_CERT'; +MASTER_SSL_CIPHER: 'MASTER_SSL_CIPHER'; +MASTER_SSL_CRL: 'MASTER_SSL_CRL'; +MASTER_SSL_CRLPATH: 'MASTER_SSL_CRLPATH'; +MASTER_SSL_KEY: 'MASTER_SSL_KEY'; +MASTER_TLS_VERSION: 'MASTER_TLS_VERSION'; +MASTER_USER: 'MASTER_USER'; +MAX_CONNECTIONS_PER_HOUR: 'MAX_CONNECTIONS_PER_HOUR'; +MAX_QUERIES_PER_HOUR: 'MAX_QUERIES_PER_HOUR'; +MAX_ROWS: 'MAX_ROWS'; +MAX_SIZE: 'MAX_SIZE'; +MAX_UPDATES_PER_HOUR: 'MAX_UPDATES_PER_HOUR'; +MAX_USER_CONNECTIONS: 'MAX_USER_CONNECTIONS'; +MEDIUM: 'MEDIUM'; +MEMBER: 'MEMBER'; +MERGE: 'MERGE'; +MESSAGE_TEXT: 'MESSAGE_TEXT'; +MID: 'MID'; +MIGRATE: 'MIGRATE'; +MIN_ROWS: 'MIN_ROWS'; +MODE: 'MODE'; +MODIFY: 'MODIFY'; +MUTEX: 'MUTEX'; +MYSQL: 'MYSQL'; +MYSQL_ERRNO: 'MYSQL_ERRNO'; +NAME: 'NAME'; +NAMES: 'NAMES'; +NCHAR: 'NCHAR'; +NEVER: 'NEVER'; +NEXT: 'NEXT'; +NO: 'NO'; +NOCACHE: 'NOCACHE'; +NOCOPY: 'NOCOPY'; +NOCYCLE: 'NOCYCLE'; +NOMAXVALUE: 'NOMAXVALUE'; +NOMINVALUE: 'NOMINVALUE'; +NOWAIT: 'NOWAIT'; +NODEGROUP: 'NODEGROUP'; +NONE: 'NONE'; +ODBC: 'ODBC'; +OFFLINE: 'OFFLINE'; +OFFSET: 'OFFSET'; +OF: 'OF'; +OJ: 'OJ'; +OLD_PASSWORD: 'OLD_PASSWORD'; +ONE: 'ONE'; +ONLINE: 'ONLINE'; +ONLY: 'ONLY'; +OPEN: 'OPEN'; +OPTIMIZER_COSTS: 'OPTIMIZER_COSTS'; +OPTIONS: 'OPTIONS'; +OWNER: 'OWNER'; +PACK_KEYS: 'PACK_KEYS'; +PAGE: 'PAGE'; +PAGE_COMPRESSED: 'PAGE_COMPRESSED'; +PAGE_COMPRESSION_LEVEL: 'PAGE_COMPRESSION_LEVEL'; +PARSER: 'PARSER'; +PARTIAL: 'PARTIAL'; +PARTITIONING: 'PARTITIONING'; +PARTITIONS: 'PARTITIONS'; +PASSWORD: 'PASSWORD'; +PASSWORD_LOCK_TIME: 'PASSWORD_LOCK_TIME'; +PHASE: 'PHASE'; +PLUGIN: 'PLUGIN'; +PLUGIN_DIR: 'PLUGIN_DIR'; +PLUGINS: 'PLUGINS'; +PORT: 'PORT'; +PRECEDES: 'PRECEDES'; +PRECEDING: 'PRECEDING'; +PREPARE: 'PREPARE'; +PRESERVE: 'PRESERVE'; +PREV: 'PREV'; +PROCESSLIST: 'PROCESSLIST'; +PROFILE: 'PROFILE'; +PROFILES: 'PROFILES'; +PROXY: 'PROXY'; +QUERY: 'QUERY'; +QUICK: 'QUICK'; +REBUILD: 'REBUILD'; +RECOVER: 'RECOVER'; +RECURSIVE: 'RECURSIVE'; +REDO_BUFFER_SIZE: 'REDO_BUFFER_SIZE'; +REDUNDANT: 'REDUNDANT'; +RELAY: 'RELAY'; +RELAY_LOG_FILE: 'RELAY_LOG_FILE'; +RELAY_LOG_POS: 'RELAY_LOG_POS'; +RELAYLOG: 'RELAYLOG'; +REMOVE: 'REMOVE'; +REORGANIZE: 'REORGANIZE'; +REPAIR: 'REPAIR'; +REPLICATE_DO_DB: 'REPLICATE_DO_DB'; +REPLICATE_DO_TABLE: 'REPLICATE_DO_TABLE'; +REPLICATE_IGNORE_DB: 'REPLICATE_IGNORE_DB'; +REPLICATE_IGNORE_TABLE: 'REPLICATE_IGNORE_TABLE'; +REPLICATE_REWRITE_DB: 'REPLICATE_REWRITE_DB'; +REPLICATE_WILD_DO_TABLE: 'REPLICATE_WILD_DO_TABLE'; +REPLICATE_WILD_IGNORE_TABLE: 'REPLICATE_WILD_IGNORE_TABLE'; +REPLICATION: 'REPLICATION'; +RESET: 'RESET'; +RESTART: 'RESTART'; +RESUME: 'RESUME'; +RETURNED_SQLSTATE: 'RETURNED_SQLSTATE'; +RETURNING: 'RETURNING'; +RETURNS: 'RETURNS'; +REUSE: 'REUSE'; +ROLE: 'ROLE'; +ROLLBACK: 'ROLLBACK'; +ROLLUP: 'ROLLUP'; +ROTATE: 'ROTATE'; +ROW: 'ROW'; +ROWS: 'ROWS'; +ROW_FORMAT: 'ROW_FORMAT'; +RTREE: 'RTREE'; +SAVEPOINT: 'SAVEPOINT'; +SCHEDULE: 'SCHEDULE'; +SECURITY: 'SECURITY'; +SEQUENCE: 'SEQUENCE'; +SERVER: 'SERVER'; +SESSION: 'SESSION'; +SHARE: 'SHARE'; +SHARED: 'SHARED'; +SIGNED: 'SIGNED'; +SIMPLE: 'SIMPLE'; +SLAVE: 'SLAVE'; +SLOW: 'SLOW'; +SNAPSHOT: 'SNAPSHOT'; +SOCKET: 'SOCKET'; +SOME: 'SOME'; +SONAME: 'SONAME'; +SOUNDS: 'SOUNDS'; +SOURCE: 'SOURCE'; +SQL_AFTER_GTIDS: 'SQL_AFTER_GTIDS'; +SQL_AFTER_MTS_GAPS: 'SQL_AFTER_MTS_GAPS'; +SQL_BEFORE_GTIDS: 'SQL_BEFORE_GTIDS'; +SQL_BUFFER_RESULT: 'SQL_BUFFER_RESULT'; +SQL_CACHE: 'SQL_CACHE'; +SQL_NO_CACHE: 'SQL_NO_CACHE'; +SQL_THREAD: 'SQL_THREAD'; +START: 'START'; +STARTS: 'STARTS'; +STATS_AUTO_RECALC: 'STATS_AUTO_RECALC'; +STATS_PERSISTENT: 'STATS_PERSISTENT'; +STATS_SAMPLE_PAGES: 'STATS_SAMPLE_PAGES'; +STATUS: 'STATUS'; +STOP: 'STOP'; +STORAGE: 'STORAGE'; +STORED: 'STORED'; +STRING: 'STRING'; +SUBCLASS_ORIGIN: 'SUBCLASS_ORIGIN'; +SUBJECT: 'SUBJECT'; +SUBPARTITION: 'SUBPARTITION'; +SUBPARTITIONS: 'SUBPARTITIONS'; +SUSPEND: 'SUSPEND'; +SWAPS: 'SWAPS'; +SWITCHES: 'SWITCHES'; +TABLE_NAME: 'TABLE_NAME'; +TABLESPACE: 'TABLESPACE'; +TABLE_TYPE: 'TABLE_TYPE'; +TEMPORARY: 'TEMPORARY'; +TEMPTABLE: 'TEMPTABLE'; +THAN: 'THAN'; +TRADITIONAL: 'TRADITIONAL'; +TRANSACTION: 'TRANSACTION'; +TRANSACTIONAL: 'TRANSACTIONAL'; +TRIGGERS: 'TRIGGERS'; +TRUNCATE: 'TRUNCATE'; +UNBOUNDED: 'UNBOUNDED'; +UNDEFINED: 'UNDEFINED'; +UNDOFILE: 'UNDOFILE'; +UNDO_BUFFER_SIZE: 'UNDO_BUFFER_SIZE'; +UNINSTALL: 'UNINSTALL'; +UNKNOWN: 'UNKNOWN'; +UNTIL: 'UNTIL'; +UPGRADE: 'UPGRADE'; +USER: 'USER'; +USE_FRM: 'USE_FRM'; +USER_RESOURCES: 'USER_RESOURCES'; +VALIDATION: 'VALIDATION'; +VALUE: 'VALUE'; +VARIABLES: 'VARIABLES'; +VIEW: 'VIEW'; +VIRTUAL: 'VIRTUAL'; +VISIBLE: 'VISIBLE'; +WAIT: 'WAIT'; +WARNINGS: 'WARNINGS'; +WINDOW: 'WINDOW'; +WITHOUT: 'WITHOUT'; +WORK: 'WORK'; +WRAPPER: 'WRAPPER'; +X509: 'X509'; +XA: 'XA'; +XML: 'XML'; +YES: 'YES'; + +// Date format Keywords + +EUR: 'EUR'; +USA: 'USA'; +JIS: 'JIS'; +ISO: 'ISO'; +INTERNAL: 'INTERNAL'; + + +// Interval type Keywords + +QUARTER: 'QUARTER'; +MONTH: 'MONTH'; +DAY: 'DAY'; +HOUR: 'HOUR'; +MINUTE: 'MINUTE'; +WEEK: 'WEEK'; +SECOND: 'SECOND'; +MICROSECOND: 'MICROSECOND'; + + +// PRIVILEGES + +ADMIN: 'ADMIN'; +APPLICATION_PASSWORD_ADMIN: 'APPLICATION_PASSWORD_ADMIN'; +AUDIT_ABORT_EXEMPT: 'AUDIT_ABORT_EXEMPT'; +AUDIT_ADMIN: 'AUDIT_ADMIN'; +AUTHENTICATION_POLICY_ADMIN: 'AUTHENTICATION_POLICY_ADMIN'; +BACKUP_ADMIN: 'BACKUP_ADMIN'; +BINLOG_ADMIN: 'BINLOG_ADMIN'; +BINLOG_ENCRYPTION_ADMIN: 'BINLOG_ENCRYPTION_ADMIN'; +CLONE_ADMIN: 'CLONE_ADMIN'; +CONNECTION_ADMIN: 'CONNECTION_ADMIN'; +ENCRYPTION_KEY_ADMIN: 'ENCRYPTION_KEY_ADMIN'; +EXECUTE: 'EXECUTE'; +FILE: 'FILE'; +FIREWALL_ADMIN: 'FIREWALL_ADMIN'; +FIREWALL_EXEMPT: 'FIREWALL_EXEMPT'; +FIREWALL_USER: 'FIREWALL_USER'; +FLUSH_OPTIMIZER_COSTS: 'FLUSH_OPTIMIZER_COSTS'; +FLUSH_STATUS: 'FLUSH_STATUS'; +FLUSH_TABLES: 'FLUSH_TABLES'; +FLUSH_USER_RESOURCES: 'FLUSH_USER_RESOURCES'; +GROUP_REPLICATION_ADMIN: 'GROUP_REPLICATION_ADMIN'; +INNODB_REDO_LOG_ARCHIVE: 'INNODB_REDO_LOG_ARCHIVE'; +INNODB_REDO_LOG_ENABLE: 'INNODB_REDO_LOG_ENABLE'; +INVOKE: 'INVOKE'; +LAMBDA: 'LAMBDA'; +NDB_STORED_USER: 'NDB_STORED_USER'; +PASSWORDLESS_USER_ADMIN: 'PASSWORDLESS_USER_ADMIN'; +PERSIST_RO_VARIABLES_ADMIN: 'PERSIST_RO_VARIABLES_ADMIN'; +PRIVILEGES: 'PRIVILEGES'; +PROCESS: 'PROCESS'; +RELOAD: 'RELOAD'; +REPLICATION_APPLIER: 'REPLICATION_APPLIER'; +REPLICATION_SLAVE_ADMIN: 'REPLICATION_SLAVE_ADMIN'; +RESOURCE_GROUP_ADMIN: 'RESOURCE_GROUP_ADMIN'; +RESOURCE_GROUP_USER: 'RESOURCE_GROUP_USER'; +ROLE_ADMIN: 'ROLE_ADMIN'; +ROUTINE: 'ROUTINE'; +S3: 'S3'; +SERVICE_CONNECTION_ADMIN: 'SERVICE_CONNECTION_ADMIN'; +SESSION_VARIABLES_ADMIN: QUOTE_SYMB? 'SESSION_VARIABLES_ADMIN' QUOTE_SYMB?; +SET_USER_ID: 'SET_USER_ID'; +SHOW_ROUTINE: 'SHOW_ROUTINE'; +SHUTDOWN: 'SHUTDOWN'; +SUPER: 'SUPER'; +SYSTEM_VARIABLES_ADMIN: 'SYSTEM_VARIABLES_ADMIN'; +TABLES: 'TABLES'; +TABLE_ENCRYPTION_ADMIN: 'TABLE_ENCRYPTION_ADMIN'; +VERSION_TOKEN_ADMIN: 'VERSION_TOKEN_ADMIN'; +XA_RECOVER_ADMIN: 'XA_RECOVER_ADMIN'; + + +// Charsets + +ARMSCII8: 'ARMSCII8'; +ASCII: 'ASCII'; +BIG5: 'BIG5'; +CP1250: 'CP1250'; +CP1251: 'CP1251'; +CP1256: 'CP1256'; +CP1257: 'CP1257'; +CP850: 'CP850'; +CP852: 'CP852'; +CP866: 'CP866'; +CP932: 'CP932'; +DEC8: 'DEC8'; +EUCJPMS: 'EUCJPMS'; +EUCKR: 'EUCKR'; +GB18030: 'GB18030'; +GB2312: 'GB2312'; +GBK: 'GBK'; +GEOSTD8: 'GEOSTD8'; +GREEK: 'GREEK'; +HEBREW: 'HEBREW'; +HP8: 'HP8'; +KEYBCS2: 'KEYBCS2'; +KOI8R: 'KOI8R'; +KOI8U: 'KOI8U'; +LATIN1: 'LATIN1'; +LATIN2: 'LATIN2'; +LATIN5: 'LATIN5'; +LATIN7: 'LATIN7'; +MACCE: 'MACCE'; +MACROMAN: 'MACROMAN'; +SJIS: 'SJIS'; +SWE7: 'SWE7'; +TIS620: 'TIS620'; +UCS2: 'UCS2'; +UJIS: 'UJIS'; +UTF16: 'UTF16'; +UTF16LE: 'UTF16LE'; +UTF32: 'UTF32'; +UTF8: 'UTF8'; +UTF8MB3: 'UTF8MB3'; +UTF8MB4: 'UTF8MB4'; + + +// DB Engines + +ARCHIVE: 'ARCHIVE'; +BLACKHOLE: 'BLACKHOLE'; +CSV: 'CSV'; +FEDERATED: 'FEDERATED'; +INNODB: 'INNODB'; +MEMORY: 'MEMORY'; +MRG_MYISAM: 'MRG_MYISAM'; +MYISAM: 'MYISAM'; +NDB: 'NDB'; +NDBCLUSTER: 'NDBCLUSTER'; +PERFORMANCE_SCHEMA: 'PERFORMANCE_SCHEMA'; +TOKUDB: 'TOKUDB'; + + +// Transaction Levels + +REPEATABLE: 'REPEATABLE'; +COMMITTED: 'COMMITTED'; +UNCOMMITTED: 'UNCOMMITTED'; +SERIALIZABLE: 'SERIALIZABLE'; + + +// Spatial data types + +GEOMETRYCOLLECTION: 'GEOMETRYCOLLECTION'; +GEOMCOLLECTION: 'GEOMCOLLECTION'; +GEOMETRY: 'GEOMETRY'; +LINESTRING: 'LINESTRING'; +MULTILINESTRING: 'MULTILINESTRING'; +MULTIPOINT: 'MULTIPOINT'; +MULTIPOLYGON: 'MULTIPOLYGON'; +POINT: 'POINT'; +POLYGON: 'POLYGON'; + + +// Common function names + +ABS: 'ABS'; +ACOS: 'ACOS'; +ADDDATE: 'ADDDATE'; +ADDTIME: 'ADDTIME'; +AES_DECRYPT: 'AES_DECRYPT'; +AES_ENCRYPT: 'AES_ENCRYPT'; +AREA: 'AREA'; +ASBINARY: 'ASBINARY'; +ASIN: 'ASIN'; +ASTEXT: 'ASTEXT'; +ASWKB: 'ASWKB'; +ASWKT: 'ASWKT'; +ASYMMETRIC_DECRYPT: 'ASYMMETRIC_DECRYPT'; +ASYMMETRIC_DERIVE: 'ASYMMETRIC_DERIVE'; +ASYMMETRIC_ENCRYPT: 'ASYMMETRIC_ENCRYPT'; +ASYMMETRIC_SIGN: 'ASYMMETRIC_SIGN'; +ASYMMETRIC_VERIFY: 'ASYMMETRIC_VERIFY'; +ATAN: 'ATAN'; +ATAN2: 'ATAN2'; +BENCHMARK: 'BENCHMARK'; +BIN: 'BIN'; +BIT_COUNT: 'BIT_COUNT'; +BIT_LENGTH: 'BIT_LENGTH'; +BUFFER: 'BUFFER'; +CATALOG_NAME: 'CATALOG_NAME'; +CEIL: 'CEIL'; +CEILING: 'CEILING'; +CENTROID: 'CENTROID'; +CHARACTER_LENGTH: 'CHARACTER_LENGTH'; +CHARSET: 'CHARSET'; +CHAR_LENGTH: 'CHAR_LENGTH'; +COERCIBILITY: 'COERCIBILITY'; +COLLATION: 'COLLATION'; +COMPRESS: 'COMPRESS'; +CONCAT: 'CONCAT'; +CONCAT_WS: 'CONCAT_WS'; +CONNECTION_ID: 'CONNECTION_ID'; +CONV: 'CONV'; +CONVERT_TZ: 'CONVERT_TZ'; +COS: 'COS'; +COT: 'COT'; +CRC32: 'CRC32'; +CREATE_ASYMMETRIC_PRIV_KEY: 'CREATE_ASYMMETRIC_PRIV_KEY'; +CREATE_ASYMMETRIC_PUB_KEY: 'CREATE_ASYMMETRIC_PUB_KEY'; +CREATE_DH_PARAMETERS: 'CREATE_DH_PARAMETERS'; +CREATE_DIGEST: 'CREATE_DIGEST'; +CROSSES: 'CROSSES'; +DATEDIFF: 'DATEDIFF'; +DATE_FORMAT: 'DATE_FORMAT'; +DAYNAME: 'DAYNAME'; +DAYOFMONTH: 'DAYOFMONTH'; +DAYOFWEEK: 'DAYOFWEEK'; +DAYOFYEAR: 'DAYOFYEAR'; +DECODE: 'DECODE'; +DEGREES: 'DEGREES'; +DES_DECRYPT: 'DES_DECRYPT'; +DES_ENCRYPT: 'DES_ENCRYPT'; +DIMENSION: 'DIMENSION'; +DISJOINT: 'DISJOINT'; +ELT: 'ELT'; +ENCODE: 'ENCODE'; +ENCRYPT: 'ENCRYPT'; +ENDPOINT: 'ENDPOINT'; +ENGINE_ATTRIBUTE: 'ENGINE_ATTRIBUTE'; +ENVELOPE: 'ENVELOPE'; +EQUALS: 'EQUALS'; +EXP: 'EXP'; +EXPORT_SET: 'EXPORT_SET'; +EXTERIORRING: 'EXTERIORRING'; +EXTRACTVALUE: 'EXTRACTVALUE'; +FIELD: 'FIELD'; +FIND_IN_SET: 'FIND_IN_SET'; +FLOOR: 'FLOOR'; +FORMAT: 'FORMAT'; +FOUND_ROWS: 'FOUND_ROWS'; +FROM_BASE64: 'FROM_BASE64'; +FROM_DAYS: 'FROM_DAYS'; +FROM_UNIXTIME: 'FROM_UNIXTIME'; +GEOMCOLLFROMTEXT: 'GEOMCOLLFROMTEXT'; +GEOMCOLLFROMWKB: 'GEOMCOLLFROMWKB'; +GEOMETRYCOLLECTIONFROMTEXT: 'GEOMETRYCOLLECTIONFROMTEXT'; +GEOMETRYCOLLECTIONFROMWKB: 'GEOMETRYCOLLECTIONFROMWKB'; +GEOMETRYFROMTEXT: 'GEOMETRYFROMTEXT'; +GEOMETRYFROMWKB: 'GEOMETRYFROMWKB'; +GEOMETRYN: 'GEOMETRYN'; +GEOMETRYTYPE: 'GEOMETRYTYPE'; +GEOMFROMTEXT: 'GEOMFROMTEXT'; +GEOMFROMWKB: 'GEOMFROMWKB'; +GET_FORMAT: 'GET_FORMAT'; +GET_LOCK: 'GET_LOCK'; +GLENGTH: 'GLENGTH'; +GREATEST: 'GREATEST'; +GTID_SUBSET: 'GTID_SUBSET'; +GTID_SUBTRACT: 'GTID_SUBTRACT'; +HEX: 'HEX'; +IFNULL: 'IFNULL'; +INET6_ATON: 'INET6_ATON'; +INET6_NTOA: 'INET6_NTOA'; +INET_ATON: 'INET_ATON'; +INET_NTOA: 'INET_NTOA'; +INSTR: 'INSTR'; +INTERIORRINGN: 'INTERIORRINGN'; +INTERSECTS: 'INTERSECTS'; +ISCLOSED: 'ISCLOSED'; +ISEMPTY: 'ISEMPTY'; +ISNULL: 'ISNULL'; +ISSIMPLE: 'ISSIMPLE'; +IS_FREE_LOCK: 'IS_FREE_LOCK'; +IS_IPV4: 'IS_IPV4'; +IS_IPV4_COMPAT: 'IS_IPV4_COMPAT'; +IS_IPV4_MAPPED: 'IS_IPV4_MAPPED'; +IS_IPV6: 'IS_IPV6'; +IS_USED_LOCK: 'IS_USED_LOCK'; +LAST_INSERT_ID: 'LAST_INSERT_ID'; +LCASE: 'LCASE'; +LEAST: 'LEAST'; +LENGTH: 'LENGTH'; +LINEFROMTEXT: 'LINEFROMTEXT'; +LINEFROMWKB: 'LINEFROMWKB'; +LINESTRINGFROMTEXT: 'LINESTRINGFROMTEXT'; +LINESTRINGFROMWKB: 'LINESTRINGFROMWKB'; +LN: 'LN'; +LOAD_FILE: 'LOAD_FILE'; +LOCATE: 'LOCATE'; +LOG: 'LOG'; +LOG10: 'LOG10'; +LOG2: 'LOG2'; +LOWER: 'LOWER'; +LPAD: 'LPAD'; +LTRIM: 'LTRIM'; +MAKEDATE: 'MAKEDATE'; +MAKETIME: 'MAKETIME'; +MAKE_SET: 'MAKE_SET'; +MASTER_POS_WAIT: 'MASTER_POS_WAIT'; +MBRCONTAINS: 'MBRCONTAINS'; +MBRDISJOINT: 'MBRDISJOINT'; +MBREQUAL: 'MBREQUAL'; +MBRINTERSECTS: 'MBRINTERSECTS'; +MBROVERLAPS: 'MBROVERLAPS'; +MBRTOUCHES: 'MBRTOUCHES'; +MBRWITHIN: 'MBRWITHIN'; +MD5: 'MD5'; +MLINEFROMTEXT: 'MLINEFROMTEXT'; +MLINEFROMWKB: 'MLINEFROMWKB'; +MONTHNAME: 'MONTHNAME'; +MPOINTFROMTEXT: 'MPOINTFROMTEXT'; +MPOINTFROMWKB: 'MPOINTFROMWKB'; +MPOLYFROMTEXT: 'MPOLYFROMTEXT'; +MPOLYFROMWKB: 'MPOLYFROMWKB'; +MULTILINESTRINGFROMTEXT: 'MULTILINESTRINGFROMTEXT'; +MULTILINESTRINGFROMWKB: 'MULTILINESTRINGFROMWKB'; +MULTIPOINTFROMTEXT: 'MULTIPOINTFROMTEXT'; +MULTIPOINTFROMWKB: 'MULTIPOINTFROMWKB'; +MULTIPOLYGONFROMTEXT: 'MULTIPOLYGONFROMTEXT'; +MULTIPOLYGONFROMWKB: 'MULTIPOLYGONFROMWKB'; +NAME_CONST: 'NAME_CONST'; +NULLIF: 'NULLIF'; +NUMGEOMETRIES: 'NUMGEOMETRIES'; +NUMINTERIORRINGS: 'NUMINTERIORRINGS'; +NUMPOINTS: 'NUMPOINTS'; +OCT: 'OCT'; +OCTET_LENGTH: 'OCTET_LENGTH'; +ORD: 'ORD'; +OVERLAPS: 'OVERLAPS'; +PERIOD_ADD: 'PERIOD_ADD'; +PERIOD_DIFF: 'PERIOD_DIFF'; +PI: 'PI'; +POINTFROMTEXT: 'POINTFROMTEXT'; +POINTFROMWKB: 'POINTFROMWKB'; +POINTN: 'POINTN'; +POLYFROMTEXT: 'POLYFROMTEXT'; +POLYFROMWKB: 'POLYFROMWKB'; +POLYGONFROMTEXT: 'POLYGONFROMTEXT'; +POLYGONFROMWKB: 'POLYGONFROMWKB'; +POW: 'POW'; +POWER: 'POWER'; +QUOTE: 'QUOTE'; +RADIANS: 'RADIANS'; +RAND: 'RAND'; +RANDOM_BYTES: 'RANDOM_BYTES'; +RELEASE_LOCK: 'RELEASE_LOCK'; +REVERSE: 'REVERSE'; +ROUND: 'ROUND'; +ROW_COUNT: 'ROW_COUNT'; +RPAD: 'RPAD'; +RTRIM: 'RTRIM'; +SEC_TO_TIME: 'SEC_TO_TIME'; +SECONDARY_ENGINE_ATTRIBUTE: 'SECONDARY_ENGINE_ATTRIBUTE'; +SESSION_USER: 'SESSION_USER'; +SHA: 'SHA'; +SHA1: 'SHA1'; +SHA2: 'SHA2'; +SCHEMA_NAME: 'SCHEMA_NAME'; +SIGN: 'SIGN'; +SIN: 'SIN'; +SLEEP: 'SLEEP'; +SOUNDEX: 'SOUNDEX'; +SQL_THREAD_WAIT_AFTER_GTIDS: 'SQL_THREAD_WAIT_AFTER_GTIDS'; +SQRT: 'SQRT'; +SRID: 'SRID'; +STARTPOINT: 'STARTPOINT'; +STRCMP: 'STRCMP'; +STR_TO_DATE: 'STR_TO_DATE'; +ST_AREA: 'ST_AREA'; +ST_ASBINARY: 'ST_ASBINARY'; +ST_ASTEXT: 'ST_ASTEXT'; +ST_ASWKB: 'ST_ASWKB'; +ST_ASWKT: 'ST_ASWKT'; +ST_BUFFER: 'ST_BUFFER'; +ST_CENTROID: 'ST_CENTROID'; +ST_CONTAINS: 'ST_CONTAINS'; +ST_CROSSES: 'ST_CROSSES'; +ST_DIFFERENCE: 'ST_DIFFERENCE'; +ST_DIMENSION: 'ST_DIMENSION'; +ST_DISJOINT: 'ST_DISJOINT'; +ST_DISTANCE: 'ST_DISTANCE'; +ST_ENDPOINT: 'ST_ENDPOINT'; +ST_ENVELOPE: 'ST_ENVELOPE'; +ST_EQUALS: 'ST_EQUALS'; +ST_EXTERIORRING: 'ST_EXTERIORRING'; +ST_GEOMCOLLFROMTEXT: 'ST_GEOMCOLLFROMTEXT'; +ST_GEOMCOLLFROMTXT: 'ST_GEOMCOLLFROMTXT'; +ST_GEOMCOLLFROMWKB: 'ST_GEOMCOLLFROMWKB'; +ST_GEOMETRYCOLLECTIONFROMTEXT: 'ST_GEOMETRYCOLLECTIONFROMTEXT'; +ST_GEOMETRYCOLLECTIONFROMWKB: 'ST_GEOMETRYCOLLECTIONFROMWKB'; +ST_GEOMETRYFROMTEXT: 'ST_GEOMETRYFROMTEXT'; +ST_GEOMETRYFROMWKB: 'ST_GEOMETRYFROMWKB'; +ST_GEOMETRYN: 'ST_GEOMETRYN'; +ST_GEOMETRYTYPE: 'ST_GEOMETRYTYPE'; +ST_GEOMFROMTEXT: 'ST_GEOMFROMTEXT'; +ST_GEOMFROMWKB: 'ST_GEOMFROMWKB'; +ST_INTERIORRINGN: 'ST_INTERIORRINGN'; +ST_INTERSECTION: 'ST_INTERSECTION'; +ST_INTERSECTS: 'ST_INTERSECTS'; +ST_ISCLOSED: 'ST_ISCLOSED'; +ST_ISEMPTY: 'ST_ISEMPTY'; +ST_ISSIMPLE: 'ST_ISSIMPLE'; +ST_LINEFROMTEXT: 'ST_LINEFROMTEXT'; +ST_LINEFROMWKB: 'ST_LINEFROMWKB'; +ST_LINESTRINGFROMTEXT: 'ST_LINESTRINGFROMTEXT'; +ST_LINESTRINGFROMWKB: 'ST_LINESTRINGFROMWKB'; +ST_NUMGEOMETRIES: 'ST_NUMGEOMETRIES'; +ST_NUMINTERIORRING: 'ST_NUMINTERIORRING'; +ST_NUMINTERIORRINGS: 'ST_NUMINTERIORRINGS'; +ST_NUMPOINTS: 'ST_NUMPOINTS'; +ST_OVERLAPS: 'ST_OVERLAPS'; +ST_POINTFROMTEXT: 'ST_POINTFROMTEXT'; +ST_POINTFROMWKB: 'ST_POINTFROMWKB'; +ST_POINTN: 'ST_POINTN'; +ST_POLYFROMTEXT: 'ST_POLYFROMTEXT'; +ST_POLYFROMWKB: 'ST_POLYFROMWKB'; +ST_POLYGONFROMTEXT: 'ST_POLYGONFROMTEXT'; +ST_POLYGONFROMWKB: 'ST_POLYGONFROMWKB'; +ST_SRID: 'ST_SRID'; +ST_STARTPOINT: 'ST_STARTPOINT'; +ST_SYMDIFFERENCE: 'ST_SYMDIFFERENCE'; +ST_TOUCHES: 'ST_TOUCHES'; +ST_UNION: 'ST_UNION'; +ST_WITHIN: 'ST_WITHIN'; +ST_X: 'ST_X'; +ST_Y: 'ST_Y'; +SUBDATE: 'SUBDATE'; +SUBSTRING_INDEX: 'SUBSTRING_INDEX'; +SUBTIME: 'SUBTIME'; +SYSTEM_USER: 'SYSTEM_USER'; +TAN: 'TAN'; +TIMEDIFF: 'TIMEDIFF'; +TIMESTAMPADD: 'TIMESTAMPADD'; +TIMESTAMPDIFF: 'TIMESTAMPDIFF'; +TIME_FORMAT: 'TIME_FORMAT'; +TIME_TO_SEC: 'TIME_TO_SEC'; +TOUCHES: 'TOUCHES'; +TO_BASE64: 'TO_BASE64'; +TO_DAYS: 'TO_DAYS'; +TO_SECONDS: 'TO_SECONDS'; +TP_CONNECTION_ADMIN: 'TP_CONNECTION_ADMIN'; +UCASE: 'UCASE'; +UNCOMPRESS: 'UNCOMPRESS'; +UNCOMPRESSED_LENGTH: 'UNCOMPRESSED_LENGTH'; +UNHEX: 'UNHEX'; +UNIX_TIMESTAMP: 'UNIX_TIMESTAMP'; +UPDATEXML: 'UPDATEXML'; +UPPER: 'UPPER'; +UUID: 'UUID'; +UUID_SHORT: 'UUID_SHORT'; +VALIDATE_PASSWORD_STRENGTH: 'VALIDATE_PASSWORD_STRENGTH'; +VERSION: 'VERSION'; +WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS: 'WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS'; +WEEKDAY: 'WEEKDAY'; +WEEKOFYEAR: 'WEEKOFYEAR'; +WEIGHT_STRING: 'WEIGHT_STRING'; +WITHIN: 'WITHIN'; +YEARWEEK: 'YEARWEEK'; +Y_FUNCTION: 'Y'; +X_FUNCTION: 'X'; + + + + +// Operators +// Operators. Assigns + +VAR_ASSIGN: ':='; +PLUS_ASSIGN: '+='; +MINUS_ASSIGN: '-='; +MULT_ASSIGN: '*='; +DIV_ASSIGN: '/='; +MOD_ASSIGN: '%='; +AND_ASSIGN: '&='; +XOR_ASSIGN: '^='; +OR_ASSIGN: '|='; + + +// Operators. Arithmetics + +STAR: '*'; +DIVIDE: '/'; +MODULE: '%'; +PLUS: '+'; +MINUS: '-'; +DIV: 'DIV'; +MOD: 'MOD'; + + +// Operators. Comparation + +EQUAL_SYMBOL: '='; +GREATER_SYMBOL: '>'; +LESS_SYMBOL: '<'; +EXCLAMATION_SYMBOL: '!'; + + +// Operators. Bit + +BIT_NOT_OP: '~'; +BIT_OR_OP: '|'; +BIT_AND_OP: '&'; +BIT_XOR_OP: '^'; + + +// Constructors symbols + +DOT: '.'; +LR_BRACKET: '('; +RR_BRACKET: ')'; +COMMA: ','; +SEMI: ';'; +AT_SIGN: '@'; +ZERO_DECIMAL: '0'; +ONE_DECIMAL: '1'; +TWO_DECIMAL: '2'; +SINGLE_QUOTE_SYMB: '\''; +DOUBLE_QUOTE_SYMB: '"'; +REVERSE_QUOTE_SYMB: '`'; +COLON_SYMB: ':'; + +fragment QUOTE_SYMB + : SINGLE_QUOTE_SYMB | DOUBLE_QUOTE_SYMB | REVERSE_QUOTE_SYMB + ; + + + +// Charsets + +CHARSET_REVERSE_QOUTE_STRING: '`' CHARSET_NAME '`'; + + + +// File's sizes + + +FILESIZE_LITERAL: DEC_DIGIT+ ('K'|'M'|'G'|'T'); + + + +// Literal Primitives + + +START_NATIONAL_STRING_LITERAL: 'N' SQUOTA_STRING; +STRING_LITERAL: DQUOTA_STRING | SQUOTA_STRING | BQUOTA_STRING; +DECIMAL_LITERAL: DEC_DIGIT+; +HEXADECIMAL_LITERAL: 'X' '\'' (HEX_DIGIT HEX_DIGIT)+ '\'' + | '0X' HEX_DIGIT+; + +REAL_LITERAL: (DEC_DIGIT+)? '.' DEC_DIGIT+ + | DEC_DIGIT+ '.' EXPONENT_NUM_PART + | (DEC_DIGIT+)? '.' (DEC_DIGIT+ EXPONENT_NUM_PART) + | DEC_DIGIT+ EXPONENT_NUM_PART; +NULL_SPEC_LITERAL: '\\' 'N'; +BIT_STRING: BIT_STRING_L; +STRING_CHARSET_NAME: '_' CHARSET_NAME; + + + + +// Hack for dotID +// Prevent recognize string: .123somelatin AS ((.123), FLOAT_LITERAL), ((somelatin), ID) +// it must recoginze: .123somelatin AS ((.), DOT), (123somelatin, ID) + +DOT_ID: '.' ID_LITERAL; + + + +// Identifiers + +ID: ID_LITERAL; +// DOUBLE_QUOTE_ID: '"' ~'"'+ '"'; +REVERSE_QUOTE_ID: '`' ~'`'+ '`'; +STRING_USER_NAME: ( + SQUOTA_STRING | DQUOTA_STRING + | BQUOTA_STRING | ID_LITERAL + ) '@' + ( + SQUOTA_STRING | DQUOTA_STRING + | BQUOTA_STRING | ID_LITERAL + | IP_ADDRESS + ); +IP_ADDRESS: ( + [0-9]+ '.' [0-9.]+ + | [0-9A-F:]+ ':' [0-9A-F:]+ + ); +LOCAL_ID: '@' + ( + [A-Z0-9._$]+ + | SQUOTA_STRING + | DQUOTA_STRING + | BQUOTA_STRING + ); +GLOBAL_ID: '@' '@' + ( + [A-Z0-9._$]+ + | BQUOTA_STRING + ); + + +// Fragments for Literal primitives + +fragment CHARSET_NAME: ARMSCII8 | ASCII | BIG5 | BINARY | CP1250 + | CP1251 | CP1256 | CP1257 | CP850 + | CP852 | CP866 | CP932 | DEC8 | EUCJPMS + | EUCKR | GB2312 | GBK | GEOSTD8 | GREEK + | HEBREW | HP8 | KEYBCS2 | KOI8R | KOI8U + | LATIN1 | LATIN2 | LATIN5 | LATIN7 + | MACCE | MACROMAN | SJIS | SWE7 | TIS620 + | UCS2 | UJIS | UTF16 | UTF16LE | UTF32 + | UTF8 | UTF8MB3 | UTF8MB4; + +fragment EXPONENT_NUM_PART: 'E' [-+]? DEC_DIGIT+; +fragment ID_LITERAL: [A-Z_$0-9\u0080-\uFFFF]*?[A-Z_$\u0080-\uFFFF]+?[A-Z_$0-9\u0080-\uFFFF]*; +fragment DQUOTA_STRING: '"' ( '\\'. | '""' | ~('"'| '\\') )* '"'; +fragment SQUOTA_STRING: '\'' ('\\'. | '\'\'' | ~('\'' | '\\'))* '\''; +fragment BQUOTA_STRING: '`' ( '\\'. | '``' | ~('`'|'\\'))* '`'; +fragment HEX_DIGIT: [0-9A-F]; +fragment DEC_DIGIT: [0-9]; +fragment BIT_STRING_L: 'B' '\'' [01]+ '\''; + + + +// Last tokens must generate Errors + +ERROR_RECONGNIGION: . -> channel(ERRORCHANNEL); diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/antlr/MySqlParser.g4 b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/antlr/MySqlParser.g4 new file mode 100644 index 0000000000..53bae6ae0f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/antlr/MySqlParser.g4 @@ -0,0 +1,2837 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +parser grammar MySqlParser; + +options { tokenVocab=MySqlLexer; } + + +// Top Level Description + +root + : sqlStatements? (MINUS MINUS)? EOF + ; + +sqlStatements + : (sqlStatement (MINUS MINUS)? SEMI? | emptyStatement_)* + (sqlStatement ((MINUS MINUS)? SEMI)? | emptyStatement_) + ; + +sqlStatement + : ddlStatement | dmlStatement | transactionStatement + | replicationStatement | preparedStatement + | administrationStatement | utilityStatement + ; + +emptyStatement_ + : SEMI + ; + +ddlStatement + : createDatabase | createEvent | createIndex + | createLogfileGroup | createProcedure | createFunction + | createServer | createTable | createTablespaceInnodb + | createTablespaceNdb | createTrigger | createView | createRole + | alterDatabase | alterEvent | alterFunction + | alterInstance | alterLogfileGroup | alterProcedure + | alterServer | alterTable | alterTablespace | alterView + | dropDatabase | dropEvent | dropIndex + | dropLogfileGroup | dropProcedure | dropFunction + | dropServer | dropTable | dropTablespace + | dropTrigger | dropView | dropRole | setRole + | renameTable | truncateTable + ; + +dmlStatement + : selectStatement | insertStatement | updateStatement + | deleteStatement | replaceStatement | callStatement + | loadDataStatement | loadXmlStatement | doStatement + | handlerStatement | valuesStatement | withStatement + ; + +transactionStatement + : startTransaction + | beginWork | commitWork | rollbackWork + | savepointStatement | rollbackStatement + | releaseStatement | lockTables | unlockTables + ; + +replicationStatement + : changeMaster | changeReplicationFilter | purgeBinaryLogs + | resetMaster | resetSlave | startSlave | stopSlave + | startGroupReplication | stopGroupReplication + | xaStartTransaction | xaEndTransaction | xaPrepareStatement + | xaCommitWork | xaRollbackWork | xaRecoverWork + ; + +preparedStatement + : prepareStatement | executeStatement | deallocatePrepare + ; + +// remark: NOT INCLUDED IN sqlStatement, but include in body +// of routine's statements +compoundStatement + : blockStatement + | caseStatement | ifStatement | leaveStatement + | loopStatement | repeatStatement | whileStatement + | iterateStatement | returnStatement | cursorStatement + ; + +administrationStatement + : alterUser | createUser | dropUser | grantStatement + | grantProxy | renameUser | revokeStatement + | revokeProxy | analyzeTable | checkTable + | checksumTable | optimizeTable | repairTable + | createUdfunction | installPlugin | uninstallPlugin + | setStatement | showStatement | binlogStatement + | cacheIndexStatement | flushStatement | killStatement + | loadIndexIntoCache | resetStatement + | shutdownStatement + ; + +utilityStatement + : simpleDescribeStatement | fullDescribeStatement + | helpStatement | useStatement | signalStatement + | resignalStatement | diagnosticsStatement + ; + + +// Data Definition Language + +// Create statements + +createDatabase + : CREATE dbFormat=(DATABASE | SCHEMA) + ifNotExists? uid createDatabaseOption* + ; + +createEvent + : CREATE ownerStatement? EVENT ifNotExists? fullId + ON SCHEDULE scheduleExpression + (ON COMPLETION NOT? PRESERVE)? enableType? + (COMMENT STRING_LITERAL)? + DO routineBody + ; + +createIndex + : CREATE + intimeAction=(ONLINE | OFFLINE)? + indexCategory=(UNIQUE | FULLTEXT | SPATIAL)? INDEX + uid indexType? + ON tableName indexColumnNames + indexOption* + ( + ALGORITHM EQUAL_SYMBOL? algType=(DEFAULT | INPLACE | COPY) + | LOCK EQUAL_SYMBOL? lockType=(DEFAULT | NONE | SHARED | EXCLUSIVE) + )* + ; + +createLogfileGroup + : CREATE LOGFILE GROUP uid + ADD UNDOFILE undoFile=STRING_LITERAL + (INITIAL_SIZE '='? initSize=fileSizeLiteral)? + (UNDO_BUFFER_SIZE '='? undoSize=fileSizeLiteral)? + (REDO_BUFFER_SIZE '='? redoSize=fileSizeLiteral)? + (NODEGROUP '='? uid)? + WAIT? + (COMMENT '='? comment=STRING_LITERAL)? + ENGINE '='? engineName + ; + +createProcedure + : CREATE ownerStatement? + PROCEDURE fullId + '(' procedureParameter? (',' procedureParameter)* ')' + routineOption* + routineBody + ; + +createFunction + : CREATE ownerStatement? AGGREGATE? + FUNCTION ifNotExists? fullId + '(' functionParameter? (',' functionParameter)* ')' + RETURNS dataType + routineOption* + (routineBody | returnStatement) + ; + +createRole + : CREATE ROLE ifNotExists? roleName (',' roleName)* + ; + +createServer + : CREATE SERVER uid + FOREIGN DATA WRAPPER wrapperName=(MYSQL | STRING_LITERAL) + OPTIONS '(' serverOption (',' serverOption)* ')' + ; + +createTable + : CREATE TEMPORARY? TABLE ifNotExists? + tableName + ( + LIKE tableName + | '(' LIKE parenthesisTable=tableName ')' + ) #copyCreateTable + | CREATE TEMPORARY? TABLE ifNotExists? + tableName createDefinitions? + ( tableOption (','? tableOption)* )? + partitionDefinitions? keyViolate=(IGNORE | REPLACE)? + AS? selectStatement #queryCreateTable + | CREATE TEMPORARY? TABLE ifNotExists? + tableName createDefinitions + ( tableOption (','? tableOption)* )? + partitionDefinitions? #columnCreateTable + ; + +createTablespaceInnodb + : CREATE TABLESPACE uid + ADD DATAFILE datafile=STRING_LITERAL + (FILE_BLOCK_SIZE '=' fileBlockSize=fileSizeLiteral)? + (ENGINE '='? engineName)? + ; + +createTablespaceNdb + : CREATE TABLESPACE uid + ADD DATAFILE datafile=STRING_LITERAL + USE LOGFILE GROUP uid + (EXTENT_SIZE '='? extentSize=fileSizeLiteral)? + (INITIAL_SIZE '='? initialSize=fileSizeLiteral)? + (AUTOEXTEND_SIZE '='? autoextendSize=fileSizeLiteral)? + (MAX_SIZE '='? maxSize=fileSizeLiteral)? + (NODEGROUP '='? uid)? + WAIT? + (COMMENT '='? comment=STRING_LITERAL)? + ENGINE '='? engineName + ; + +createTrigger + : CREATE ownerStatement? + TRIGGER thisTrigger=fullId + triggerTime=(BEFORE | AFTER) + triggerEvent=(INSERT | UPDATE | DELETE) + ON tableName FOR EACH ROW + (triggerPlace=(FOLLOWS | PRECEDES) otherTrigger=fullId)? + routineBody + ; + +withClause + : WITH RECURSIVE? commonTableExpressions + ; + +commonTableExpressions + : cteName ('(' cteColumnName (',' cteColumnName)* ')')? AS '(' dmlStatement ')' + (',' commonTableExpressions)? + ; + +cteName + : uid + ; + +cteColumnName + : uid + ; + +createView + : CREATE orReplace? + ( + ALGORITHM '=' algType=(UNDEFINED | MERGE | TEMPTABLE) + )? + ownerStatement? + (SQL SECURITY secContext=(DEFINER | INVOKER))? + VIEW fullId ('(' uidList ')')? AS + ( + '(' withClause? selectStatement ')' + | + withClause? selectStatement (WITH checkOption=(CASCADED | LOCAL)? CHECK OPTION)? + ) + ; + + +// details + +createDatabaseOption + : DEFAULT? charSet '='? (charsetName | DEFAULT) + | DEFAULT? COLLATE '='? collationName + | DEFAULT? ENCRYPTION '='? STRING_LITERAL + | READ ONLY '='? (DEFAULT | ZERO_DECIMAL | ONE_DECIMAL) + ; + +charSet + : CHARACTER SET + | CHARSET + | CHAR SET + ; + +ownerStatement + : DEFINER '=' (userName | CURRENT_USER ( '(' ')')?) + ; + +scheduleExpression + : AT timestampValue intervalExpr* #preciseSchedule + | EVERY (decimalLiteral | expression) intervalType + ( + STARTS startTimestamp=timestampValue + (startIntervals+=intervalExpr)* + )? + ( + ENDS endTimestamp=timestampValue + (endIntervals+=intervalExpr)* + )? #intervalSchedule + ; + +timestampValue + : CURRENT_TIMESTAMP + | stringLiteral + | decimalLiteral + | expression + ; + +intervalExpr + : '+' INTERVAL (decimalLiteral | expression) intervalType + ; + +intervalType + : intervalTypeBase + | YEAR | YEAR_MONTH | DAY_HOUR | DAY_MINUTE + | DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND + | SECOND_MICROSECOND | MINUTE_MICROSECOND + | HOUR_MICROSECOND | DAY_MICROSECOND + ; + +enableType + : ENABLE | DISABLE | DISABLE ON SLAVE + ; + +indexType + : USING (BTREE | HASH) + ; + +indexOption + : KEY_BLOCK_SIZE EQUAL_SYMBOL? fileSizeLiteral + | indexType + | WITH PARSER uid + | COMMENT STRING_LITERAL + | (VISIBLE | INVISIBLE) + | ENGINE_ATTRIBUTE EQUAL_SYMBOL? STRING_LITERAL + | SECONDARY_ENGINE_ATTRIBUTE EQUAL_SYMBOL? STRING_LITERAL + ; + +procedureParameter + : direction=(IN | OUT | INOUT)? uid dataType + ; + +functionParameter + : uid dataType + ; + +routineOption + : COMMENT STRING_LITERAL #routineComment + | LANGUAGE SQL #routineLanguage + | NOT? DETERMINISTIC #routineBehavior + | ( + CONTAINS SQL | NO SQL | READS SQL DATA + | MODIFIES SQL DATA + ) #routineData + | SQL SECURITY context=(DEFINER | INVOKER) #routineSecurity + ; + +serverOption + : HOST STRING_LITERAL + | DATABASE STRING_LITERAL + | USER STRING_LITERAL + | PASSWORD STRING_LITERAL + | SOCKET STRING_LITERAL + | OWNER STRING_LITERAL + | PORT decimalLiteral + ; + +createDefinitions + : '(' createDefinition (',' createDefinition)* ')' + ; + +createDefinition + : fullColumnName columnDefinition #columnDeclaration + | tableConstraint NOT? ENFORCED? #constraintDeclaration + | indexColumnDefinition #indexDeclaration + ; + +columnDefinition + : dataType columnConstraint* NOT? ENFORCED? + ; + +columnConstraint + : nullNotnull #nullColumnConstraint + | DEFAULT defaultValue #defaultColumnConstraint + | VISIBLE #visibilityColumnConstraint + | INVISIBLE #invisibilityColumnConstraint + | (AUTO_INCREMENT | ON UPDATE currentTimestamp) #autoIncrementColumnConstraint + | PRIMARY? KEY #primaryKeyColumnConstraint + | UNIQUE KEY? #uniqueKeyColumnConstraint + | COMMENT STRING_LITERAL #commentColumnConstraint + | COLUMN_FORMAT colformat=(FIXED | DYNAMIC | DEFAULT) #formatColumnConstraint + | STORAGE storageval=(DISK | MEMORY | DEFAULT) #storageColumnConstraint + | referenceDefinition #referenceColumnConstraint + | COLLATE collationName #collateColumnConstraint + | (GENERATED ALWAYS)? AS '(' expression ')' (VIRTUAL | STORED)? #generatedColumnConstraint + | SERIAL DEFAULT VALUE #serialDefaultColumnConstraint + | (CONSTRAINT name=uid?)? + CHECK '(' expression ')' #checkColumnConstraint + ; + +tableConstraint + : (CONSTRAINT name=uid?)? + PRIMARY KEY index=uid? indexType? + indexColumnNames indexOption* #primaryKeyTableConstraint + | (CONSTRAINT name=uid?)? + UNIQUE indexFormat=(INDEX | KEY)? index=uid? + indexType? indexColumnNames indexOption* #uniqueKeyTableConstraint + | (CONSTRAINT name=uid?)? + FOREIGN KEY index=uid? indexColumnNames + referenceDefinition #foreignKeyTableConstraint + | (CONSTRAINT name=uid?)? + CHECK '(' expression ')' #checkTableConstraint + ; + +referenceDefinition + : REFERENCES tableName indexColumnNames? + (MATCH matchType=(FULL | PARTIAL | SIMPLE))? + referenceAction? + ; + +referenceAction + : ON DELETE onDelete=referenceControlType + ( + ON UPDATE onUpdate=referenceControlType + )? + | ON UPDATE onUpdate=referenceControlType + ( + ON DELETE onDelete=referenceControlType + )? + ; + +referenceControlType + : RESTRICT | CASCADE | SET NULL_LITERAL | NO ACTION | SET DEFAULT + ; + +indexColumnDefinition + : indexFormat=(INDEX | KEY) uid? indexType? + indexColumnNames indexOption* #simpleIndexDeclaration + | (FULLTEXT | SPATIAL) + indexFormat=(INDEX | KEY)? uid? + indexColumnNames indexOption* #specialIndexDeclaration + ; + +tableOption + : ENGINE '='? engineName? #tableOptionEngine + | ENGINE_ATTRIBUTE '='? STRING_LITERAL #tableOptionEngineAttribute + | AUTOEXTEND_SIZE '='? decimalLiteral #tableOptionAutoextendSize + | AUTO_INCREMENT '='? decimalLiteral #tableOptionAutoIncrement + | AVG_ROW_LENGTH '='? decimalLiteral #tableOptionAverage + | DEFAULT? charSet '='? (charsetName|DEFAULT) #tableOptionCharset + | (CHECKSUM | PAGE_CHECKSUM) '='? boolValue=('0' | '1') #tableOptionChecksum + | DEFAULT? COLLATE '='? collationName #tableOptionCollate + | COMMENT '='? STRING_LITERAL #tableOptionComment + | COMPRESSION '='? (STRING_LITERAL | ID) #tableOptionCompression + | CONNECTION '='? STRING_LITERAL #tableOptionConnection + | (DATA | INDEX) DIRECTORY '='? STRING_LITERAL #tableOptionDataDirectory + | DELAY_KEY_WRITE '='? boolValue=('0' | '1') #tableOptionDelay + | ENCRYPTION '='? STRING_LITERAL #tableOptionEncryption + | (PAGE_COMPRESSED | STRING_LITERAL) '='? ('0' | '1') #tableOptionPageCompressed + | (PAGE_COMPRESSION_LEVEL | STRING_LITERAL) '='? decimalLiteral #tableOptionPageCompressionLevel + | ENCRYPTION_KEY_ID '='? decimalLiteral #tableOptionEncryptionKeyId + | INDEX DIRECTORY '='? STRING_LITERAL #tableOptionIndexDirectory + | INSERT_METHOD '='? insertMethod=(NO | FIRST | LAST) #tableOptionInsertMethod + | KEY_BLOCK_SIZE '='? fileSizeLiteral #tableOptionKeyBlockSize + | MAX_ROWS '='? decimalLiteral #tableOptionMaxRows + | MIN_ROWS '='? decimalLiteral #tableOptionMinRows + | PACK_KEYS '='? extBoolValue=('0' | '1' | DEFAULT) #tableOptionPackKeys + | PASSWORD '='? STRING_LITERAL #tableOptionPassword + | ROW_FORMAT '='? + rowFormat=( + DEFAULT | DYNAMIC | FIXED | COMPRESSED + | REDUNDANT | COMPACT | ID + ) #tableOptionRowFormat + | START TRANSACTION #tableOptionStartTransaction + | SECONDARY_ENGINE_ATTRIBUTE '='? STRING_LITERAL #tableOptionSecondaryEngineAttribute + | STATS_AUTO_RECALC '='? extBoolValue=(DEFAULT | '0' | '1') #tableOptionRecalculation + | STATS_PERSISTENT '='? extBoolValue=(DEFAULT | '0' | '1') #tableOptionPersistent + | STATS_SAMPLE_PAGES '='? (DEFAULT | decimalLiteral) #tableOptionSamplePage + | TABLESPACE uid tablespaceStorage? #tableOptionTablespace + | TABLE_TYPE '=' tableType #tableOptionTableType + | tablespaceStorage #tableOptionTablespace + | TRANSACTIONAL '='? ('0' | '1') #tableOptionTransactional + | UNION '='? '(' tables ')' #tableOptionUnion + ; + +tableType + : MYSQL | ODBC + ; + +tablespaceStorage + : STORAGE (DISK | MEMORY | DEFAULT) + ; + +partitionDefinitions + : PARTITION BY partitionFunctionDefinition + (PARTITIONS count=decimalLiteral)? + ( + SUBPARTITION BY subpartitionFunctionDefinition + (SUBPARTITIONS subCount=decimalLiteral)? + )? + ('(' partitionDefinition (',' partitionDefinition)* ')')? + ; + +partitionFunctionDefinition + : LINEAR? HASH '(' expression ')' #partitionFunctionHash + | LINEAR? KEY (ALGORITHM '=' algType=('1' | '2'))? + '(' uidList? ')' #partitionFunctionKey // Optional uidList for MySQL only + | RANGE ( '(' expression ')' | COLUMNS '(' uidList ')' ) #partitionFunctionRange + | LIST ( '(' expression ')' | COLUMNS '(' uidList ')' ) #partitionFunctionList + ; + +subpartitionFunctionDefinition + : LINEAR? HASH '(' expression ')' #subPartitionFunctionHash + | LINEAR? KEY (ALGORITHM '=' algType=('1' | '2'))? + '(' uidList ')' #subPartitionFunctionKey + ; + +partitionDefinition + : PARTITION uid VALUES LESS THAN + '(' + partitionDefinerAtom (',' partitionDefinerAtom)* + ')' + partitionOption* + ( '(' subpartitionDefinition (',' subpartitionDefinition)* ')' )? #partitionComparison + | PARTITION uid VALUES LESS THAN + partitionDefinerAtom partitionOption* + ( '(' subpartitionDefinition (',' subpartitionDefinition)* ')' )? #partitionComparison + | PARTITION uid VALUES IN + '(' + partitionDefinerAtom (',' partitionDefinerAtom)* + ')' + partitionOption* + ( '(' subpartitionDefinition (',' subpartitionDefinition)* ')' )? #partitionListAtom + | PARTITION uid VALUES IN + '(' + partitionDefinerVector (',' partitionDefinerVector)* + ')' + partitionOption* + ( '(' subpartitionDefinition (',' subpartitionDefinition)* ')' )? #partitionListVector + | PARTITION uid partitionOption* + ( '(' subpartitionDefinition (',' subpartitionDefinition)* ')' )? #partitionSimple + ; + +partitionDefinerAtom + : constant | expression | MAXVALUE + ; + +partitionDefinerVector + : '(' partitionDefinerAtom (',' partitionDefinerAtom)+ ')' + ; + +subpartitionDefinition + : SUBPARTITION uid partitionOption* + ; + +partitionOption + : DEFAULT? STORAGE? ENGINE '='? engineName #partitionOptionEngine + | COMMENT '='? comment=STRING_LITERAL #partitionOptionComment + | DATA DIRECTORY '='? dataDirectory=STRING_LITERAL #partitionOptionDataDirectory + | INDEX DIRECTORY '='? indexDirectory=STRING_LITERAL #partitionOptionIndexDirectory + | MAX_ROWS '='? maxRows=decimalLiteral #partitionOptionMaxRows + | MIN_ROWS '='? minRows=decimalLiteral #partitionOptionMinRows + | TABLESPACE '='? tablespace=uid #partitionOptionTablespace + | NODEGROUP '='? nodegroup=uid #partitionOptionNodeGroup + ; + +// Alter statements + +alterDatabase + : ALTER dbFormat=(DATABASE | SCHEMA) uid? + createDatabaseOption+ #alterSimpleDatabase + | ALTER dbFormat=(DATABASE | SCHEMA) uid + UPGRADE DATA DIRECTORY NAME #alterUpgradeName + ; + +alterEvent + : ALTER ownerStatement? + EVENT fullId + (ON SCHEDULE scheduleExpression)? + (ON COMPLETION NOT? PRESERVE)? + (RENAME TO fullId)? enableType? + (COMMENT STRING_LITERAL)? + (DO routineBody)? + ; + +alterFunction + : ALTER FUNCTION fullId routineOption* + ; + +alterInstance + : ALTER INSTANCE ROTATE INNODB MASTER KEY + ; + +alterLogfileGroup + : ALTER LOGFILE GROUP uid + ADD UNDOFILE STRING_LITERAL + (INITIAL_SIZE '='? fileSizeLiteral)? + WAIT? ENGINE '='? engineName + ; + +alterProcedure + : ALTER PROCEDURE fullId routineOption* + ; + +alterServer + : ALTER SERVER uid OPTIONS + '(' serverOption (',' serverOption)* ')' + ; + +alterTable + : ALTER intimeAction=(ONLINE | OFFLINE)? + IGNORE? TABLE tableName waitNowaitClause? + (alterSpecification (',' alterSpecification)*)? + partitionDefinitions? + ; + +alterTablespace + : ALTER TABLESPACE uid + objectAction=(ADD | DROP) DATAFILE STRING_LITERAL + (INITIAL_SIZE '=' fileSizeLiteral)? + WAIT? + ENGINE '='? engineName + ; + +alterView + : ALTER + ( + ALGORITHM '=' algType=(UNDEFINED | MERGE | TEMPTABLE) + )? + ownerStatement? + (SQL SECURITY secContext=(DEFINER | INVOKER))? + VIEW fullId ('(' uidList ')')? AS selectStatement + (WITH checkOpt=(CASCADED | LOCAL)? CHECK OPTION)? + ; + +// details + +alterSpecification + : tableOption (','? tableOption)* #alterByTableOption + | ADD COLUMN? uid columnDefinition (FIRST | AFTER uid)? #alterByAddColumn + | ADD COLUMN? + '(' + uid columnDefinition ( ',' uid columnDefinition)* + ')' #alterByAddColumns + | ADD indexFormat=(INDEX | KEY) uid? indexType? + indexColumnNames indexOption* #alterByAddIndex + | ADD (CONSTRAINT name=uid?)? PRIMARY KEY index=uid? + indexType? indexColumnNames indexOption* #alterByAddPrimaryKey + | ADD (CONSTRAINT name=uid?)? UNIQUE + indexFormat=(INDEX | KEY)? indexName=uid? + indexType? indexColumnNames indexOption* #alterByAddUniqueKey + | ADD keyType=(FULLTEXT | SPATIAL) + indexFormat=(INDEX | KEY)? uid? + indexColumnNames indexOption* #alterByAddSpecialIndex + | ADD (CONSTRAINT name=uid?)? FOREIGN KEY + indexName=uid? indexColumnNames referenceDefinition #alterByAddForeignKey + | ADD (CONSTRAINT name=uid?)? CHECK ( uid | stringLiteral | '(' expression ')' ) + NOT? ENFORCED? #alterByAddCheckTableConstraint + | ALTER (CONSTRAINT name=uid?)? CHECK ( uid | stringLiteral | '(' expression ')' ) + NOT? ENFORCED? #alterByAlterCheckTableConstraint + | ADD (CONSTRAINT name=uid?)? CHECK '(' expression ')' #alterByAddCheckTableConstraint + | ALGORITHM '='? algType=(DEFAULT | INSTANT | INPLACE | COPY) #alterBySetAlgorithm + | ALTER COLUMN? uid + (SET DEFAULT defaultValue | DROP DEFAULT) #alterByChangeDefault + | CHANGE COLUMN? oldColumn=uid + newColumn=uid columnDefinition + (FIRST | AFTER afterColumn=uid)? #alterByChangeColumn + | RENAME COLUMN oldColumn=uid TO newColumn=uid #alterByRenameColumn + | LOCK '='? lockType=(DEFAULT | NONE | SHARED | EXCLUSIVE) #alterByLock + | MODIFY COLUMN? + uid columnDefinition (FIRST | AFTER uid)? #alterByModifyColumn + | DROP COLUMN? uid RESTRICT? #alterByDropColumn + | DROP (CONSTRAINT | CHECK) uid #alterByDropConstraintCheck + | DROP PRIMARY KEY #alterByDropPrimaryKey + | DROP indexFormat=(INDEX | KEY) uid #alterByDropIndex + | RENAME indexFormat=(INDEX | KEY) uid TO uid #alterByRenameIndex + | ALTER COLUMN? uid ( + SET DEFAULT ( stringLiteral | '(' expression ')' ) + | SET (VISIBLE | INVISIBLE) + | DROP DEFAULT) #alterByAlterColumnDefault + | ALTER INDEX uid (VISIBLE | INVISIBLE) #alterByAlterIndexVisibility + | DROP FOREIGN KEY uid #alterByDropForeignKey + | DISABLE KEYS #alterByDisableKeys + | ENABLE KEYS #alterByEnableKeys + | RENAME renameFormat=(TO | AS)? (uid | fullId) #alterByRename + | ORDER BY uidList #alterByOrder + | CONVERT TO (CHARSET | CHARACTER SET) charsetName + (COLLATE collationName)? #alterByConvertCharset + | DEFAULT? CHARACTER SET '=' charsetName + (COLLATE '=' collationName)? #alterByDefaultCharset + | DISCARD TABLESPACE #alterByDiscardTablespace + | IMPORT TABLESPACE #alterByImportTablespace + | FORCE #alterByForce + | validationFormat=(WITHOUT | WITH) VALIDATION #alterByValidate + | ADD PARTITION + '(' + partitionDefinition (',' partitionDefinition)* + ')' #alterByAddPartition + | DROP PARTITION uidList #alterByDropPartition + | DISCARD PARTITION (uidList | ALL) TABLESPACE #alterByDiscardPartition + | IMPORT PARTITION (uidList | ALL) TABLESPACE #alterByImportPartition + | TRUNCATE PARTITION (uidList | ALL) #alterByTruncatePartition + | COALESCE PARTITION decimalLiteral #alterByCoalescePartition + | REORGANIZE PARTITION uidList + INTO '(' + partitionDefinition (',' partitionDefinition)* + ')' #alterByReorganizePartition + | EXCHANGE PARTITION uid WITH TABLE tableName + (validationFormat=(WITH | WITHOUT) VALIDATION)? #alterByExchangePartition + | ANALYZE PARTITION (uidList | ALL) #alterByAnalyzePartition + | CHECK PARTITION (uidList | ALL) #alterByCheckPartition + | OPTIMIZE PARTITION (uidList | ALL) #alterByOptimizePartition + | REBUILD PARTITION (uidList | ALL) #alterByRebuildPartition + | REPAIR PARTITION (uidList | ALL) #alterByRepairPartition + | REMOVE PARTITIONING #alterByRemovePartitioning + | UPGRADE PARTITIONING #alterByUpgradePartitioning + | ADD COLUMN? + '(' createDefinition (',' createDefinition)* ')' #alterByAddDefinitions + ; + + +// Drop statements + +dropDatabase + : DROP dbFormat=(DATABASE | SCHEMA) ifExists? uid + ; + +dropEvent + : DROP EVENT ifExists? fullId + ; + +dropIndex + : DROP INDEX intimeAction=(ONLINE | OFFLINE)? + uid ON tableName + ( + ALGORITHM '='? algType=(DEFAULT | INPLACE | COPY) + | LOCK '='? + lockType=(DEFAULT | NONE | SHARED | EXCLUSIVE) + )* + ; + +dropLogfileGroup + : DROP LOGFILE GROUP uid ENGINE '=' engineName + ; + +dropProcedure + : DROP PROCEDURE ifExists? fullId + ; + +dropFunction + : DROP FUNCTION ifExists? fullId + ; + +dropServer + : DROP SERVER ifExists? uid + ; + +dropTable + : DROP TEMPORARY? TABLE ifExists? + tables dropType=(RESTRICT | CASCADE)? + ; + +dropTablespace + : DROP TABLESPACE uid (ENGINE '='? engineName)? + ; + +dropTrigger + : DROP TRIGGER ifExists? fullId + ; + +dropView + : DROP VIEW ifExists? + fullId (',' fullId)* dropType=(RESTRICT | CASCADE)? + ; + +dropRole + : DROP ROLE ifExists? roleName (',' roleName)* + ; + +setRole + : SET DEFAULT ROLE (NONE | ALL | roleName (',' roleName)*) + TO (userName | uid) (',' (userName | uid))* + | SET ROLE roleOption + ; + +// Other DDL statements + +renameTable + : RENAME TABLE + renameTableClause (',' renameTableClause)* + ; + +renameTableClause + : tableName TO tableName + ; + +truncateTable + : TRUNCATE TABLE? tableName + ; + + +// Data Manipulation Language + +// Primary DML Statements + + +callStatement + : CALL fullId + ( + '(' (constants | expressions)? ')' + )? + ; + +deleteStatement + : singleDeleteStatement | multipleDeleteStatement + ; + +doStatement + : DO expressions + ; + +handlerStatement + : handlerOpenStatement + | handlerReadIndexStatement + | handlerReadStatement + | handlerCloseStatement + ; + +insertStatement + : INSERT + priority=(LOW_PRIORITY | DELAYED | HIGH_PRIORITY)? + IGNORE? INTO? tableName + (PARTITION '(' partitions=uidList? ')' )? + ( + ('(' columns=fullColumnNameList ')')? insertStatementValue (AS? uid)? + | SET + setFirst=updatedElement + (',' setElements+=updatedElement)* + ) + ( + ON DUPLICATE KEY UPDATE + duplicatedFirst=updatedElement + (',' duplicatedElements+=updatedElement)* + )? + ; + +loadDataStatement + : LOAD DATA + priority=(LOW_PRIORITY | CONCURRENT)? + LOCAL? INFILE filename=STRING_LITERAL + violation=(REPLACE | IGNORE)? + INTO TABLE tableName + (PARTITION '(' uidList ')' )? + (CHARACTER SET charset=charsetName)? + ( + fieldsFormat=(FIELDS | COLUMNS) + selectFieldsInto+ + )? + ( + LINES + selectLinesInto+ + )? + ( + IGNORE decimalLiteral linesFormat=(LINES | ROWS) + )? + ( '(' assignmentField (',' assignmentField)* ')' )? + (SET updatedElement (',' updatedElement)*)? + ; + +loadXmlStatement + : LOAD XML + priority=(LOW_PRIORITY | CONCURRENT)? + LOCAL? INFILE filename=STRING_LITERAL + violation=(REPLACE | IGNORE)? + INTO TABLE tableName + (CHARACTER SET charset=charsetName)? + (ROWS IDENTIFIED BY '<' tag=STRING_LITERAL '>')? + ( IGNORE decimalLiteral linesFormat=(LINES | ROWS) )? + ( '(' assignmentField (',' assignmentField)* ')' )? + (SET updatedElement (',' updatedElement)*)? + ; + +replaceStatement + : REPLACE priority=(LOW_PRIORITY | DELAYED)? + INTO? tableName + (PARTITION '(' partitions=uidList ')' )? + ( + ('(' columns=uidList ')')? insertStatementValue + | SET + setFirst=updatedElement + (',' setElements+=updatedElement)* + ) + ; + +selectStatement + : querySpecification lockClause? #simpleSelect + | queryExpression lockClause? #parenthesisSelect + | querySpecificationNointo unionStatement+ + ( + UNION unionType=(ALL | DISTINCT)? + (querySpecification | queryExpression) + )? + orderByClause? limitClause? lockClause? #unionSelect + | queryExpressionNointo unionParenthesis+ + ( + UNION unionType=(ALL | DISTINCT)? + queryExpression + )? + orderByClause? limitClause? lockClause? #unionParenthesisSelect + | querySpecificationNointo (',' lateralStatement)+ #withLateralStatement + ; + +updateStatement + : singleUpdateStatement | multipleUpdateStatement + ; + +// https://dev.mysql.com/doc/refman/8.0/en/values.html +valuesStatement + : VALUES + '(' expressionsWithDefaults? ')' + (',' '(' expressionsWithDefaults? ')')* + ; + +// details + +insertStatementValue + : selectStatement + | insertFormat=(VALUES | VALUE) + '(' expressionsWithDefaults? ')' + (',' '(' expressionsWithDefaults? ')')* + ; + +updatedElement + : fullColumnName '=' (expression | DEFAULT) + ; + +assignmentField + : uid | LOCAL_ID + ; + +lockClause + : FOR UPDATE | LOCK IN SHARE MODE + ; + +// Detailed DML Statements + +singleDeleteStatement + : DELETE priority=LOW_PRIORITY? QUICK? IGNORE? + FROM tableName (AS? uid)? + (PARTITION '(' uidList ')' )? + (WHERE expression)? + orderByClause? (LIMIT limitClauseAtom)? + ; + +multipleDeleteStatement + : DELETE priority=LOW_PRIORITY? QUICK? IGNORE? + ( + tableName ('.' '*')? ( ',' tableName ('.' '*')? )* + FROM tableSources + | FROM + tableName ('.' '*')? ( ',' tableName ('.' '*')? )* + USING tableSources + ) + (WHERE expression)? + ; + +handlerOpenStatement + : HANDLER tableName OPEN (AS? uid)? + ; + +handlerReadIndexStatement + : HANDLER tableName READ index=uid + ( + comparisonOperator '(' constants ')' + | moveOrder=(FIRST | NEXT | PREV | LAST) + ) + (WHERE expression)? (LIMIT limitClauseAtom)? + ; + +handlerReadStatement + : HANDLER tableName READ moveOrder=(FIRST | NEXT) + (WHERE expression)? (LIMIT limitClauseAtom)? + ; + +handlerCloseStatement + : HANDLER tableName CLOSE + ; + +singleUpdateStatement + : UPDATE priority=LOW_PRIORITY? IGNORE? tableName (AS? uid)? + SET updatedElement (',' updatedElement)* + (WHERE expression)? orderByClause? limitClause? + ; + +multipleUpdateStatement + : UPDATE priority=LOW_PRIORITY? IGNORE? tableSources + SET updatedElement (',' updatedElement)* + (WHERE expression)? + ; + +// details + +orderByClause + : ORDER BY orderByExpression (',' orderByExpression)* + ; + +orderByExpression + : expression order=(ASC | DESC)? + ; + +tableSources + : tableSource (',' tableSource)* + ; + +tableSource + : tableSourceItem joinPart* #tableSourceBase + | '(' tableSourceItem joinPart* ')' #tableSourceNested + | jsonTable #tableJson + ; + +tableSourceItem + : tableName + (PARTITION '(' uidList ')' )? (AS? alias=uid)? + (indexHint (',' indexHint)* )? #atomTableItem + | ( + selectStatement + | '(' parenthesisSubquery=selectStatement ')' + ) + AS? alias=uid #subqueryTableItem + | '(' tableSources ')' #tableSourcesItem + ; + +indexHint + : indexHintAction=(USE | IGNORE | FORCE) + keyFormat=(INDEX|KEY) ( FOR indexHintType)? + '(' uidList ')' + ; + +indexHintType + : JOIN | ORDER BY | GROUP BY + ; + +joinPart + : (INNER | CROSS)? JOIN LATERAL? tableSourceItem + ( + ON expression + | USING '(' uidList ')' + )? #innerJoin + | STRAIGHT_JOIN tableSourceItem (ON expression)? #straightJoin + | (LEFT | RIGHT) OUTER? JOIN LATERAL? tableSourceItem + ( + ON expression + | USING '(' uidList ')' + ) #outerJoin + | NATURAL ((LEFT | RIGHT) OUTER?)? JOIN tableSourceItem #naturalJoin + ; + +// Select Statement's Details + +queryExpression + : '(' querySpecification ')' + | '(' queryExpression ')' + ; + +queryExpressionNointo + : '(' querySpecificationNointo ')' + | '(' queryExpressionNointo ')' + ; + +querySpecification + : SELECT selectSpec* selectElements selectIntoExpression? + fromClause groupByClause? havingClause? windowClause? orderByClause? limitClause? + | SELECT selectSpec* selectElements + fromClause groupByClause? havingClause? windowClause? orderByClause? limitClause? selectIntoExpression? + ; + +querySpecificationNointo + : SELECT selectSpec* selectElements + fromClause groupByClause? havingClause? windowClause? orderByClause? limitClause? + ; + +unionParenthesis + : UNION unionType=(ALL | DISTINCT)? queryExpressionNointo + ; + +unionStatement + : UNION unionType=(ALL | DISTINCT)? + (querySpecificationNointo | queryExpressionNointo) + ; + +lateralStatement + : LATERAL (querySpecificationNointo | + queryExpressionNointo | + ('(' (querySpecificationNointo | queryExpressionNointo) ')' (AS? uid)?) + ) + ; + +// JSON + +// https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html +jsonTable + : JSON_TABLE '(' + STRING_LITERAL ',' + STRING_LITERAL + COLUMNS '(' jsonColumnList ')' + ')' (AS? uid)? + ; + +jsonColumnList + : jsonColumn (',' jsonColumn)* + ; + +jsonColumn + : fullColumnName ( FOR ORDINALITY + | dataType ( PATH STRING_LITERAL jsonOnEmpty? jsonOnError? + | EXISTS PATH STRING_LITERAL ) ) + | NESTED PATH? STRING_LITERAL COLUMNS '(' jsonColumnList ')' + ; + +jsonOnEmpty + : (NULL_LITERAL | ERROR | DEFAULT defaultValue) ON EMPTY + ; + +jsonOnError + : (NULL_LITERAL | ERROR | DEFAULT defaultValue) ON ERROR + ; + +// details + +selectSpec + : (ALL | DISTINCT | DISTINCTROW) + | HIGH_PRIORITY | STRAIGHT_JOIN | SQL_SMALL_RESULT + | SQL_BIG_RESULT | SQL_BUFFER_RESULT + | (SQL_CACHE | SQL_NO_CACHE) + | SQL_CALC_FOUND_ROWS + ; + +selectElements + : (star='*' | selectElement ) (',' selectElement)* + ; + +selectElement + : fullId '.' '*' #selectStarElement + | fullColumnName (AS? uid)? #selectColumnElement + | functionCall (AS? uid)? #selectFunctionElement + | (LOCAL_ID VAR_ASSIGN)? expression (AS? uid)? #selectExpressionElement + ; + +selectIntoExpression + : INTO assignmentField (',' assignmentField )* #selectIntoVariables + | INTO DUMPFILE STRING_LITERAL #selectIntoDumpFile + | ( + INTO OUTFILE filename=STRING_LITERAL + (CHARACTER SET charset=charsetName)? + ( + fieldsFormat=(FIELDS | COLUMNS) + selectFieldsInto+ + )? + ( + LINES selectLinesInto+ + )? + ) #selectIntoTextFile + ; + +selectFieldsInto + : TERMINATED BY terminationField=STRING_LITERAL + | OPTIONALLY? ENCLOSED BY enclosion=STRING_LITERAL + | ESCAPED BY escaping=STRING_LITERAL + ; + +selectLinesInto + : STARTING BY starting=STRING_LITERAL + | TERMINATED BY terminationLine=STRING_LITERAL + ; + +fromClause + : (FROM tableSources)? + (WHERE whereExpr=expression)? + ; + +groupByClause + : GROUP BY + groupByItem (',' groupByItem)* + (WITH ROLLUP)? + ; + +havingClause + : HAVING havingExpr=expression + ; + +windowClause + : WINDOW windowName AS '(' windowSpec ')' (',' windowName AS '(' windowSpec ')')* + ; + +groupByItem + : expression order=(ASC | DESC)? + ; + +limitClause + : LIMIT + ( + (offset=limitClauseAtom ',')? limit=limitClauseAtom + | limit=limitClauseAtom OFFSET offset=limitClauseAtom + ) + ; + +limitClauseAtom + : decimalLiteral | mysqlVariable | simpleId + ; + + +// Transaction's Statements + +startTransaction + : START TRANSACTION (transactionMode (',' transactionMode)* )? + ; + +beginWork + : BEGIN WORK? + ; + +commitWork + : COMMIT WORK? + (AND nochain=NO? CHAIN)? + (norelease=NO? RELEASE)? + ; + +rollbackWork + : ROLLBACK WORK? + (AND nochain=NO? CHAIN)? + (norelease=NO? RELEASE)? + ; + +savepointStatement + : SAVEPOINT uid + ; + +rollbackStatement + : ROLLBACK WORK? TO SAVEPOINT? uid + ; + +releaseStatement + : RELEASE SAVEPOINT uid + ; + +lockTables + : LOCK (TABLE | TABLES) lockTableElement (',' lockTableElement)* waitNowaitClause? + ; + +unlockTables + : UNLOCK TABLES + ; + + +// details + +setAutocommitStatement + : SET AUTOCOMMIT '=' autocommitValue=('0' | '1') + ; + +setTransactionStatement + : SET transactionContext=(GLOBAL | SESSION)? TRANSACTION + transactionOption (',' transactionOption)* + ; + +transactionMode + : WITH CONSISTENT SNAPSHOT + | READ WRITE + | READ ONLY + ; + +lockTableElement + : tableName (AS? uid)? lockAction + ; + +lockAction + : READ LOCAL? | LOW_PRIORITY? WRITE + ; + +transactionOption + : ISOLATION LEVEL transactionLevel + | READ WRITE + | READ ONLY + ; + +transactionLevel + : REPEATABLE READ + | READ COMMITTED + | READ UNCOMMITTED + | SERIALIZABLE + ; + + +// Replication's Statements + +// Base Replication + +changeMaster + : CHANGE MASTER TO + masterOption (',' masterOption)* channelOption? + ; + +changeReplicationFilter + : CHANGE REPLICATION FILTER + replicationFilter (',' replicationFilter)* + ; + +purgeBinaryLogs + : PURGE purgeFormat=(BINARY | MASTER) LOGS + ( + TO fileName=STRING_LITERAL + | BEFORE timeValue=STRING_LITERAL + ) + ; + +resetMaster + : RESET MASTER + ; + +resetSlave + : RESET SLAVE ALL? channelOption? + ; + +startSlave + : START SLAVE (threadType (',' threadType)*)? + (UNTIL untilOption)? + connectionOption* channelOption? + ; + +stopSlave + : STOP SLAVE (threadType (',' threadType)*)? + ; + +startGroupReplication + : START GROUP_REPLICATION + ; + +stopGroupReplication + : STOP GROUP_REPLICATION + ; + +// details + +masterOption + : stringMasterOption '=' STRING_LITERAL #masterStringOption + | decimalMasterOption '=' decimalLiteral #masterDecimalOption + | boolMasterOption '=' boolVal=('0' | '1') #masterBoolOption + | MASTER_HEARTBEAT_PERIOD '=' REAL_LITERAL #masterRealOption + | IGNORE_SERVER_IDS '=' '(' (uid (',' uid)*)? ')' #masterUidListOption + ; + +stringMasterOption + : MASTER_BIND | MASTER_HOST | MASTER_USER | MASTER_PASSWORD + | MASTER_LOG_FILE | RELAY_LOG_FILE | MASTER_SSL_CA + | MASTER_SSL_CAPATH | MASTER_SSL_CERT | MASTER_SSL_CRL + | MASTER_SSL_CRLPATH | MASTER_SSL_KEY | MASTER_SSL_CIPHER + | MASTER_TLS_VERSION + ; +decimalMasterOption + : MASTER_PORT | MASTER_CONNECT_RETRY | MASTER_RETRY_COUNT + | MASTER_DELAY | MASTER_LOG_POS | RELAY_LOG_POS + ; + +boolMasterOption + : MASTER_AUTO_POSITION | MASTER_SSL + | MASTER_SSL_VERIFY_SERVER_CERT + ; + +channelOption + : FOR CHANNEL STRING_LITERAL + ; + +replicationFilter + : REPLICATE_DO_DB '=' '(' uidList ')' #doDbReplication + | REPLICATE_IGNORE_DB '=' '(' uidList ')' #ignoreDbReplication + | REPLICATE_DO_TABLE '=' '(' tables ')' #doTableReplication + | REPLICATE_IGNORE_TABLE '=' '(' tables ')' #ignoreTableReplication + | REPLICATE_WILD_DO_TABLE '=' '(' simpleStrings ')' #wildDoTableReplication + | REPLICATE_WILD_IGNORE_TABLE + '=' '(' simpleStrings ')' #wildIgnoreTableReplication + | REPLICATE_REWRITE_DB '=' + '(' tablePair (',' tablePair)* ')' #rewriteDbReplication + ; + +tablePair + : '(' firstTable=tableName ',' secondTable=tableName ')' + ; + +threadType + : IO_THREAD | SQL_THREAD + ; + +untilOption + : gtids=(SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS) + '=' gtuidSet #gtidsUntilOption + | MASTER_LOG_FILE '=' STRING_LITERAL + ',' MASTER_LOG_POS '=' decimalLiteral #masterLogUntilOption + | RELAY_LOG_FILE '=' STRING_LITERAL + ',' RELAY_LOG_POS '=' decimalLiteral #relayLogUntilOption + | SQL_AFTER_MTS_GAPS #sqlGapsUntilOption + ; + +connectionOption + : USER '=' conOptUser=STRING_LITERAL #userConnectionOption + | PASSWORD '=' conOptPassword=STRING_LITERAL #passwordConnectionOption + | DEFAULT_AUTH '=' conOptDefAuth=STRING_LITERAL #defaultAuthConnectionOption + | PLUGIN_DIR '=' conOptPluginDir=STRING_LITERAL #pluginDirConnectionOption + ; + +gtuidSet + : uuidSet (',' uuidSet)* + | STRING_LITERAL + ; + + +// XA Transactions + +xaStartTransaction + : XA xaStart=(START | BEGIN) xid xaAction=(JOIN | RESUME)? + ; + +xaEndTransaction + : XA END xid (SUSPEND (FOR MIGRATE)?)? + ; + +xaPrepareStatement + : XA PREPARE xid + ; + +xaCommitWork + : XA COMMIT xid (ONE PHASE)? + ; + +xaRollbackWork + : XA ROLLBACK xid + ; + +xaRecoverWork + : XA RECOVER (CONVERT xid)? + ; + + +// Prepared Statements + +prepareStatement + : PREPARE uid FROM + (query=STRING_LITERAL | variable=LOCAL_ID) + ; + +executeStatement + : EXECUTE uid (USING userVariables)? + ; + +deallocatePrepare + : dropFormat=(DEALLOCATE | DROP) PREPARE uid + ; + + +// Compound Statements + +routineBody + : blockStatement | sqlStatement + ; + +// details + +blockStatement + : (uid ':')? BEGIN + (declareVariable SEMI)* + (declareCondition SEMI)* + (declareCursor SEMI)* + (declareHandler SEMI)* + procedureSqlStatement* + END uid? + ; + +caseStatement + : CASE (uid | expression)? caseAlternative+ + (ELSE procedureSqlStatement+)? + END CASE + ; + +ifStatement + : IF expression + THEN thenStatements+=procedureSqlStatement+ + elifAlternative* + (ELSE elseStatements+=procedureSqlStatement+ )? + END IF + ; + +iterateStatement + : ITERATE uid + ; + +leaveStatement + : LEAVE uid + ; + +loopStatement + : (uid ':')? + LOOP procedureSqlStatement+ + END LOOP uid? + ; + +repeatStatement + : (uid ':')? + REPEAT procedureSqlStatement+ + UNTIL expression + END REPEAT uid? + ; + +returnStatement + : RETURN expression + ; + +whileStatement + : (uid ':')? + WHILE expression + DO procedureSqlStatement+ + END WHILE uid? + ; + +cursorStatement + : CLOSE uid #CloseCursor + | FETCH (NEXT? FROM)? uid INTO uidList #FetchCursor + | OPEN uid #OpenCursor + ; + +// details + +declareVariable + : DECLARE uidList dataType (DEFAULT expression)? + ; + +declareCondition + : DECLARE uid CONDITION FOR + ( decimalLiteral | SQLSTATE VALUE? STRING_LITERAL) + ; + +declareCursor + : DECLARE uid CURSOR FOR selectStatement + ; + +declareHandler + : DECLARE handlerAction=(CONTINUE | EXIT | UNDO) + HANDLER FOR + handlerConditionValue (',' handlerConditionValue)* + routineBody + ; + +handlerConditionValue + : decimalLiteral #handlerConditionCode + | SQLSTATE VALUE? STRING_LITERAL #handlerConditionState + | uid #handlerConditionName + | SQLWARNING #handlerConditionWarning + | NOT FOUND #handlerConditionNotfound + | SQLEXCEPTION #handlerConditionException + ; + +procedureSqlStatement + : (compoundStatement | sqlStatement) SEMI + ; + +caseAlternative + : WHEN (constant | expression) + THEN procedureSqlStatement+ + ; + +elifAlternative + : ELSEIF expression + THEN procedureSqlStatement+ + ; + +// Administration Statements + +// Account management statements + +alterUser + : ALTER USER + userSpecification (',' userSpecification)* #alterUserMysqlV56 + | ALTER USER ifExists? + userAuthOption (',' userAuthOption)* + ( + REQUIRE + (tlsNone=NONE | tlsOption (AND? tlsOption)* ) + )? + (WITH userResourceOption+)? + (userPasswordOption | userLockOption)* + (COMMENT STRING_LITERAL | ATTRIBUTE STRING_LITERAL)? #alterUserMysqlV80 + | ALTER USER ifExists? + (userName | uid) DEFAULT ROLE roleOption #alterUserMysqlV80 + ; + +createUser + : CREATE USER userAuthOption (',' userAuthOption)* #createUserMysqlV56 + | CREATE USER ifNotExists? + userAuthOption (',' userAuthOption)* + (DEFAULT ROLE roleOption)? + ( + REQUIRE + (tlsNone=NONE | tlsOption (AND? tlsOption)* ) + )? + (WITH userResourceOption+)? + (userPasswordOption | userLockOption)* + (COMMENT STRING_LITERAL | ATTRIBUTE STRING_LITERAL)? #createUserMysqlV80 + ; + +dropUser + : DROP USER ifExists? userName (',' userName)* + ; + +grantStatement + : GRANT privelegeClause (',' privelegeClause)* + ON + privilegeObject=(TABLE | FUNCTION | PROCEDURE)? + privilegeLevel + TO userAuthOption (',' userAuthOption)* + ( + REQUIRE + (tlsNone=NONE | tlsOption (AND? tlsOption)* ) + )? + (WITH (GRANT OPTION | userResourceOption)* )? + (AS userName WITH ROLE roleOption)? + | GRANT (userName | uid) (',' (userName | uid))* + TO (userName | uid) (',' (userName | uid))* + (WITH ADMIN OPTION)? + ; + +roleOption + : DEFAULT + | NONE + | ALL (EXCEPT userName (',' userName)*)? + | userName (',' userName)* + ; + +grantProxy + : GRANT PROXY ON fromFirst=userName + TO toFirst=userName (',' toOther+=userName)* + (WITH GRANT OPTION)? + ; + +renameUser + : RENAME USER + renameUserClause (',' renameUserClause)* + ; + +revokeStatement + : REVOKE privelegeClause (',' privelegeClause)* + ON + privilegeObject=(TABLE | FUNCTION | PROCEDURE)? + privilegeLevel + FROM userName (',' userName)* #detailRevoke + | REVOKE ALL PRIVILEGES? ',' GRANT OPTION + FROM userName (',' userName)* #shortRevoke + | REVOKE (userName | uid) (',' (userName | uid))* + FROM (userName | uid) (',' (userName | uid))* #roleRevoke + ; + +revokeProxy + : REVOKE PROXY ON onUser=userName + FROM fromFirst=userName (',' fromOther+=userName)* + ; + +setPasswordStatement + : SET PASSWORD (FOR userName)? + '=' ( passwordFunctionClause | STRING_LITERAL) + ; + +// details + +userSpecification + : userName userPasswordOption + ; + +userAuthOption + : userName IDENTIFIED BY PASSWORD hashed=STRING_LITERAL #hashAuthOption + | userName + IDENTIFIED BY STRING_LITERAL (RETAIN CURRENT PASSWORD)? #stringAuthOption + | userName + IDENTIFIED WITH + authenticationRule #moduleAuthOption + | userName #simpleAuthOption + ; + +authenticationRule + : authPlugin + ((BY | USING | AS) STRING_LITERAL)? #module + | authPlugin + USING passwordFunctionClause #passwordModuleOption + ; + +tlsOption + : SSL + | X509 + | CIPHER STRING_LITERAL + | ISSUER STRING_LITERAL + | SUBJECT STRING_LITERAL + ; + +userResourceOption + : MAX_QUERIES_PER_HOUR decimalLiteral + | MAX_UPDATES_PER_HOUR decimalLiteral + | MAX_CONNECTIONS_PER_HOUR decimalLiteral + | MAX_USER_CONNECTIONS decimalLiteral + ; + +userPasswordOption + : PASSWORD EXPIRE + (expireType=DEFAULT + | expireType=NEVER + | expireType=INTERVAL decimalLiteral DAY + )? + | PASSWORD HISTORY (DEFAULT | decimalLiteral) + | PASSWORD REUSE INTERVAL (DEFAULT | decimalLiteral DAY) + | PASSWORD REQUIRE CURRENT (OPTIONAL | DEFAULT)? + | FAILED_LOGIN_ATTEMPTS decimalLiteral + | PASSWORD_LOCK_TIME (decimalLiteral | UNBOUNDED) + ; + +userLockOption + : ACCOUNT lockType=(LOCK | UNLOCK) + ; + +privelegeClause + : privilege ( '(' uidList ')' )? + ; + +privilege + : ALL PRIVILEGES? + | ALTER ROUTINE? + | CREATE + (TEMPORARY TABLES | ROUTINE | VIEW | USER | TABLESPACE | ROLE)? + | DELETE | DROP (ROLE)? | EVENT | EXECUTE | FILE | GRANT OPTION + | INDEX | INSERT | LOCK TABLES | PROCESS | PROXY + | REFERENCES | RELOAD + | REPLICATION (CLIENT | SLAVE) + | SELECT + | SHOW (VIEW | DATABASES) + | SHUTDOWN | SUPER | TRIGGER | UPDATE | USAGE + | APPLICATION_PASSWORD_ADMIN | AUDIT_ABORT_EXEMPT | AUDIT_ADMIN | AUTHENTICATION_POLICY_ADMIN | BACKUP_ADMIN | BINLOG_ADMIN | BINLOG_ENCRYPTION_ADMIN | CLONE_ADMIN + | CONNECTION_ADMIN | ENCRYPTION_KEY_ADMIN | FIREWALL_ADMIN | FIREWALL_EXEMPT | FIREWALL_USER | FLUSH_OPTIMIZER_COSTS + | FLUSH_STATUS | FLUSH_TABLES | FLUSH_USER_RESOURCES | GROUP_REPLICATION_ADMIN + | INNODB_REDO_LOG_ARCHIVE | INNODB_REDO_LOG_ENABLE | NDB_STORED_USER | PASSWORDLESS_USER_ADMIN | PERSIST_RO_VARIABLES_ADMIN | REPLICATION_APPLIER + | REPLICATION_SLAVE_ADMIN | RESOURCE_GROUP_ADMIN | RESOURCE_GROUP_USER | ROLE_ADMIN + | SERVICE_CONNECTION_ADMIN + | SESSION_VARIABLES_ADMIN | SET_USER_ID | SKIP_QUERY_REWRITE | SHOW_ROUTINE | SYSTEM_USER | SYSTEM_VARIABLES_ADMIN + | TABLE_ENCRYPTION_ADMIN | TP_CONNECTION_ADMIN | VERSION_TOKEN_ADMIN | XA_RECOVER_ADMIN + // MySQL on Amazon RDS + | LOAD FROM S3 | SELECT INTO S3 | INVOKE LAMBDA + ; + +privilegeLevel + : '*' #currentSchemaPriviLevel + | '*' '.' '*' #globalPrivLevel + | uid '.' '*' #definiteSchemaPrivLevel + | uid '.' uid #definiteFullTablePrivLevel + | uid dottedId #definiteFullTablePrivLevel2 + | uid #definiteTablePrivLevel + ; + +renameUserClause + : fromFirst=userName TO toFirst=userName + ; + +// Table maintenance statements + +analyzeTable + : ANALYZE actionOption=(NO_WRITE_TO_BINLOG | LOCAL)? + (TABLE | TABLES) tables + ( UPDATE HISTOGRAM ON fullColumnName (',' fullColumnName)* (WITH decimalLiteral BUCKETS)? )? + ( DROP HISTOGRAM ON fullColumnName (',' fullColumnName)* )? + ; + +checkTable + : CHECK TABLE tables checkTableOption* + ; + +checksumTable + : CHECKSUM TABLE tables actionOption=(QUICK | EXTENDED)? + ; + +optimizeTable + : OPTIMIZE actionOption=(NO_WRITE_TO_BINLOG | LOCAL)? + (TABLE | TABLES) tables + ; + +repairTable + : REPAIR actionOption=(NO_WRITE_TO_BINLOG | LOCAL)? + TABLE tables + QUICK? EXTENDED? USE_FRM? + ; + +// details + +checkTableOption + : FOR UPGRADE | QUICK | FAST | MEDIUM | EXTENDED | CHANGED + ; + + +// Plugin and udf statements + +createUdfunction + : CREATE AGGREGATE? FUNCTION ifNotExists? uid + RETURNS returnType=(STRING | INTEGER | REAL | DECIMAL) + SONAME STRING_LITERAL + ; + +installPlugin + : INSTALL PLUGIN uid SONAME STRING_LITERAL + ; + +uninstallPlugin + : UNINSTALL PLUGIN uid + ; + + +// Set and show statements + +setStatement + : SET variableClause ('=' | ':=') (expression | ON) + (',' variableClause ('=' | ':=') (expression | ON))* #setVariable + | SET charSet (charsetName | DEFAULT) #setCharset + | SET NAMES + (charsetName (COLLATE collationName)? | DEFAULT) #setNames + | setPasswordStatement #setPassword + | setTransactionStatement #setTransaction + | setAutocommitStatement #setAutocommit + | SET fullId ('=' | ':=') expression + (',' fullId ('=' | ':=') expression)* #setNewValueInsideTrigger + ; + +showStatement + : SHOW logFormat=(BINARY | MASTER) LOGS #showMasterLogs + | SHOW logFormat=(BINLOG | RELAYLOG) + EVENTS (IN filename=STRING_LITERAL)? + (FROM fromPosition=decimalLiteral)? + (LIMIT + (offset=decimalLiteral ',')? + rowCount=decimalLiteral + )? #showLogEvents + | SHOW showCommonEntity showFilter? #showObjectFilter + | SHOW FULL? columnsFormat=(COLUMNS | FIELDS) + tableFormat=(FROM | IN) tableName + (schemaFormat=(FROM | IN) uid)? showFilter? #showColumns + | SHOW CREATE schemaFormat=(DATABASE | SCHEMA) + ifNotExists? uid #showCreateDb + | SHOW CREATE + namedEntity=( + EVENT | FUNCTION | PROCEDURE + | TABLE | TRIGGER | VIEW + ) + fullId #showCreateFullIdObject + | SHOW CREATE USER userName #showCreateUser + | SHOW ENGINE engineName engineOption=(STATUS | MUTEX) #showEngine + | SHOW showGlobalInfoClause #showGlobalInfo + | SHOW errorFormat=(ERRORS | WARNINGS) + (LIMIT + (offset=decimalLiteral ',')? + rowCount=decimalLiteral + )? #showErrors + | SHOW COUNT '(' '*' ')' errorFormat=(ERRORS | WARNINGS) #showCountErrors + | SHOW showSchemaEntity + (schemaFormat=(FROM | IN) uid)? showFilter? #showSchemaFilter + | SHOW routine=(FUNCTION | PROCEDURE) CODE fullId #showRoutine + | SHOW GRANTS (FOR userName)? #showGrants + | SHOW indexFormat=(INDEX | INDEXES | KEYS) + tableFormat=(FROM | IN) tableName + (schemaFormat=(FROM | IN) uid)? (WHERE expression)? #showIndexes + | SHOW OPEN TABLES ( schemaFormat=(FROM | IN) uid)? + showFilter? #showOpenTables + | SHOW PROFILE showProfileType (',' showProfileType)* + (FOR QUERY queryCount=decimalLiteral)? + (LIMIT + (offset=decimalLiteral ',')? + rowCount=decimalLiteral + ) #showProfile + | SHOW SLAVE STATUS (FOR CHANNEL STRING_LITERAL)? #showSlaveStatus + ; + +// details + +variableClause + : LOCAL_ID | GLOBAL_ID | ( ('@' '@')? (GLOBAL | SESSION | LOCAL) )? uid + ; + +showCommonEntity + : CHARACTER SET | COLLATION | DATABASES | SCHEMAS + | FUNCTION STATUS | PROCEDURE STATUS + | (GLOBAL | SESSION)? (STATUS | VARIABLES) + ; + +showFilter + : LIKE STRING_LITERAL + | WHERE expression + ; + +showGlobalInfoClause + : STORAGE? ENGINES | MASTER STATUS | PLUGINS + | PRIVILEGES | FULL? PROCESSLIST | PROFILES + | SLAVE HOSTS | AUTHORS | CONTRIBUTORS + ; + +showSchemaEntity + : EVENTS | TABLE STATUS | FULL? TABLES | TRIGGERS + ; + +showProfileType + : ALL | BLOCK IO | CONTEXT SWITCHES | CPU | IPC | MEMORY + | PAGE FAULTS | SOURCE | SWAPS + ; + + +// Other administrative statements + +binlogStatement + : BINLOG STRING_LITERAL + ; + +cacheIndexStatement + : CACHE INDEX tableIndexes (',' tableIndexes)* + ( PARTITION '(' (uidList | ALL) ')' )? + IN schema=uid + ; + +flushStatement + : FLUSH flushFormat=(NO_WRITE_TO_BINLOG | LOCAL)? + flushOption (',' flushOption)* + ; + +killStatement + : KILL connectionFormat=(CONNECTION | QUERY)? expression + ; + +loadIndexIntoCache + : LOAD INDEX INTO CACHE + loadedTableIndexes (',' loadedTableIndexes)* + ; + +// remark reset (maser | slave) describe in replication's +// statements section +resetStatement + : RESET QUERY CACHE + ; + +shutdownStatement + : SHUTDOWN + ; + +// details + +tableIndexes + : tableName ( indexFormat=(INDEX | KEY)? '(' uidList ')' )? + ; + +flushOption + : ( + DES_KEY_FILE | HOSTS + | ( + BINARY | ENGINE | ERROR | GENERAL | RELAY | SLOW + )? LOGS + | OPTIMIZER_COSTS | PRIVILEGES | QUERY CACHE | STATUS + | USER_RESOURCES | TABLES (WITH READ LOCK)? + ) #simpleFlushOption + | RELAY LOGS channelOption? #channelFlushOption + | (TABLE | TABLES) tables? flushTableOption? #tableFlushOption + ; + +flushTableOption + : WITH READ LOCK + | FOR EXPORT + ; + +loadedTableIndexes + : tableName + ( PARTITION '(' (partitionList=uidList | ALL) ')' )? + ( indexFormat=(INDEX | KEY)? '(' indexList=uidList ')' )? + (IGNORE LEAVES)? + ; + + +// Utility Statements + + +simpleDescribeStatement + : command=(EXPLAIN | DESCRIBE | DESC) tableName + (column=uid | pattern=STRING_LITERAL)? + ; + +fullDescribeStatement + : command=(EXPLAIN | DESCRIBE | DESC) + ( + formatType=(EXTENDED | PARTITIONS | FORMAT ) + '=' + formatValue=(TRADITIONAL | JSON) + )? + describeObjectClause + ; + +helpStatement + : HELP STRING_LITERAL + ; + +useStatement + : USE uid + ; + +signalStatement + : SIGNAL ( ( SQLSTATE VALUE? stringLiteral ) | ID | REVERSE_QUOTE_ID ) + ( SET signalConditionInformation ( ',' signalConditionInformation)* )? + ; + +resignalStatement + : RESIGNAL ( ( SQLSTATE VALUE? stringLiteral ) | ID | REVERSE_QUOTE_ID )? + ( SET signalConditionInformation ( ',' signalConditionInformation)* )? + ; + +signalConditionInformation + : ( CLASS_ORIGIN + | SUBCLASS_ORIGIN + | MESSAGE_TEXT + | MYSQL_ERRNO + | CONSTRAINT_CATALOG + | CONSTRAINT_SCHEMA + | CONSTRAINT_NAME + | CATALOG_NAME + | SCHEMA_NAME + | TABLE_NAME + | COLUMN_NAME + | CURSOR_NAME + ) '=' ( stringLiteral | DECIMAL_LITERAL | mysqlVariable | simpleId ) + ; + +withStatement + : WITH RECURSIVE? commonTableExpressions (',' commonTableExpressions)* + ; + +diagnosticsStatement + : GET ( CURRENT | STACKED )? DIAGNOSTICS ( + ( variableClause '=' ( NUMBER | ROW_COUNT ) ( ',' variableClause '=' ( NUMBER | ROW_COUNT ) )* ) + | ( CONDITION ( decimalLiteral | variableClause ) variableClause '=' diagnosticsConditionInformationName ( ',' variableClause '=' diagnosticsConditionInformationName )* ) + ) + ; + +diagnosticsConditionInformationName + : CLASS_ORIGIN + | SUBCLASS_ORIGIN + | RETURNED_SQLSTATE + | MESSAGE_TEXT + | MYSQL_ERRNO + | CONSTRAINT_CATALOG + | CONSTRAINT_SCHEMA + | CONSTRAINT_NAME + | CATALOG_NAME + | SCHEMA_NAME + | TABLE_NAME + | COLUMN_NAME + | CURSOR_NAME + ; + +// details + +describeObjectClause + : ( + selectStatement | deleteStatement | insertStatement + | replaceStatement | updateStatement + ) #describeStatements + | FOR CONNECTION uid #describeConnection + ; + + +// Common Clauses + +// DB Objects + +fullId + : uid (DOT_ID | '.' uid)? + ; + +tableName + : fullId + ; + +roleName + : userName | uid + ; + +fullColumnName + : uid (dottedId dottedId? )? + | .? dottedId dottedId? + ; + +indexColumnName + : ((uid | STRING_LITERAL) ('(' decimalLiteral ')')? | expression) sortType=(ASC | DESC)? + ; + +userName + : STRING_USER_NAME | ID | STRING_LITERAL | ADMIN | keywordsCanBeId; + +mysqlVariable + : LOCAL_ID + | GLOBAL_ID + ; + +charsetName + : BINARY + | charsetNameBase + | STRING_LITERAL + | CHARSET_REVERSE_QOUTE_STRING + ; + +collationName + : uid | STRING_LITERAL; + +engineName + : ARCHIVE | BLACKHOLE | CSV | FEDERATED | INNODB | MEMORY + | MRG_MYISAM | MYISAM | NDB | NDBCLUSTER | PERFORMANCE_SCHEMA + | TOKUDB + | ID + | STRING_LITERAL | REVERSE_QUOTE_ID + | CONNECT + ; + +uuidSet + : decimalLiteral '-' decimalLiteral '-' decimalLiteral + '-' decimalLiteral '-' decimalLiteral + (':' decimalLiteral '-' decimalLiteral)+ + ; + +xid + : globalTableUid=xuidStringId + ( + ',' qualifier=xuidStringId + (',' idFormat=decimalLiteral)? + )? + ; + +xuidStringId + : STRING_LITERAL + | BIT_STRING + | HEXADECIMAL_LITERAL+ + ; + +authPlugin + : uid | STRING_LITERAL + ; + +uid + : simpleId + //| DOUBLE_QUOTE_ID + | REVERSE_QUOTE_ID + | CHARSET_REVERSE_QOUTE_STRING + ; + +simpleId + : ID + | charsetNameBase + | transactionLevelBase + | engineName + | privilegesBase + | intervalTypeBase + | dataTypeBase + | keywordsCanBeId + | scalarFunctionName + ; + +dottedId + : DOT_ID + | '.' uid + ; + + +// Literals + +decimalLiteral + : DECIMAL_LITERAL | ZERO_DECIMAL | ONE_DECIMAL | TWO_DECIMAL | REAL_LITERAL + ; + +fileSizeLiteral + : FILESIZE_LITERAL | decimalLiteral; + +stringLiteral + : ( + STRING_CHARSET_NAME? STRING_LITERAL + | START_NATIONAL_STRING_LITERAL + ) STRING_LITERAL+ + | ( + STRING_CHARSET_NAME? STRING_LITERAL + | START_NATIONAL_STRING_LITERAL + ) (COLLATE collationName)? + ; + +booleanLiteral + : TRUE | FALSE; + +hexadecimalLiteral + : STRING_CHARSET_NAME? HEXADECIMAL_LITERAL; + +nullNotnull + : NOT? (NULL_LITERAL | NULL_SPEC_LITERAL) + ; + +constant + : stringLiteral | decimalLiteral + | '-' decimalLiteral + | hexadecimalLiteral | booleanLiteral + | REAL_LITERAL | BIT_STRING + | NOT? nullLiteral=(NULL_LITERAL | NULL_SPEC_LITERAL) + ; + + +// Data Types + +dataType + : typeName=( + CHAR | CHARACTER | VARCHAR | TINYTEXT | TEXT | MEDIUMTEXT | LONGTEXT + | NCHAR | NVARCHAR | LONG + ) + VARYING? + lengthOneDimension? BINARY? + (charSet charsetName)? + (COLLATE collationName | BINARY)? #stringDataType + | NATIONAL typeName=(CHAR | CHARACTER) VARYING + lengthOneDimension? BINARY? #nationalVaryingStringDataType + | NATIONAL typeName=(VARCHAR | CHARACTER | CHAR) + lengthOneDimension? BINARY? #nationalStringDataType + | NCHAR typeName=VARCHAR + lengthOneDimension? BINARY? #nationalStringDataType + | typeName=( + TINYINT | SMALLINT | MEDIUMINT | INT | INTEGER | BIGINT + | MIDDLEINT | INT1 | INT2 | INT3 | INT4 | INT8 + ) + lengthOneDimension? (SIGNED | UNSIGNED | ZEROFILL)* #dimensionDataType + | typeName=REAL + lengthTwoDimension? (SIGNED | UNSIGNED | ZEROFILL)* #dimensionDataType + | typeName=DOUBLE PRECISION? + lengthTwoDimension? (SIGNED | UNSIGNED | ZEROFILL)* #dimensionDataType + | typeName=(DECIMAL | DEC | FIXED | NUMERIC | FLOAT | FLOAT4 | FLOAT8) + lengthTwoOptionalDimension? (SIGNED | UNSIGNED | ZEROFILL)* #dimensionDataType + | typeName=( + DATE | TINYBLOB | MEDIUMBLOB | LONGBLOB + | BOOL | BOOLEAN | SERIAL + ) #simpleDataType + | typeName=( + BIT | TIME | TIMESTAMP | DATETIME | BINARY + | VARBINARY | BLOB | YEAR + ) + lengthOneDimension? #dimensionDataType + | typeName=(ENUM | SET) + collectionOptions BINARY? + (charSet charsetName)? #collectionDataType + | typeName=( + GEOMETRYCOLLECTION | GEOMCOLLECTION | LINESTRING | MULTILINESTRING + | MULTIPOINT | MULTIPOLYGON | POINT | POLYGON | JSON | GEOMETRY + ) (SRID decimalLiteral)? #spatialDataType + | typeName=LONG VARCHAR? + BINARY? + (charSet charsetName)? + (COLLATE collationName)? #longVarcharDataType // LONG VARCHAR is the same as LONG + | LONG VARBINARY #longVarbinaryDataType + ; + +collectionOptions + : '(' STRING_LITERAL (',' STRING_LITERAL)* ')' + ; + +convertedDataType + : + ( + typeName=(BINARY| NCHAR) lengthOneDimension? + | typeName=CHAR lengthOneDimension? (charSet charsetName)? + | typeName=(DATE | DATETIME | TIME | JSON | INT | INTEGER) + | typeName=DECIMAL lengthTwoOptionalDimension? + | (SIGNED | UNSIGNED) INTEGER? + ) ARRAY? + ; + +lengthOneDimension + : '(' decimalLiteral ')' + ; + +lengthTwoDimension + : '(' decimalLiteral ',' decimalLiteral ')' + ; + +lengthTwoOptionalDimension + : '(' decimalLiteral (',' decimalLiteral)? ')' + ; + + +// Common Lists + +uidList + : uid (',' uid)* + ; + +fullColumnNameList + : fullColumnName (',' fullColumnName)* + ; + +tables + : tableName (',' tableName)* + ; + +indexColumnNames + : '(' indexColumnName (',' indexColumnName)* ')' + ; + +expressions + : expression (',' expression)* + ; + +expressionsWithDefaults + : expressionOrDefault (',' expressionOrDefault)* + ; + +constants + : constant (',' constant)* + ; + +simpleStrings + : STRING_LITERAL (',' STRING_LITERAL)* + ; + +userVariables + : LOCAL_ID (',' LOCAL_ID)* + ; + + +// Common Expressons + +defaultValue + : NULL_LITERAL + | CAST '(' expression AS convertedDataType ')' + | unaryOperator? constant + | currentTimestamp (ON UPDATE currentTimestamp)? + | '(' expression ')' + | '(' fullId ')' + ; + +currentTimestamp + : + ( + (CURRENT_TIMESTAMP | LOCALTIME | LOCALTIMESTAMP) + ('(' decimalLiteral? ')')? + | NOW '(' decimalLiteral? ')' + ) + ; + +expressionOrDefault + : expression | DEFAULT + ; + +ifExists + : IF EXISTS + ; + + +ifNotExists + : IF NOT EXISTS + ; + +orReplace + : OR REPLACE + ; + +waitNowaitClause + : WAIT decimalLiteral + | NOWAIT + ; + +// Functions + +functionCall + : specificFunction #specificFunctionCall + | aggregateWindowedFunction #aggregateFunctionCall + | nonAggregateWindowedFunction #nonAggregateFunctionCall + | scalarFunctionName '(' functionArgs? ')' #scalarFunctionCall + | fullId '(' functionArgs? ')' #udfFunctionCall + | passwordFunctionClause #passwordFunctionCall + ; + +specificFunction + : ( + CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP + | CURRENT_USER | LOCALTIME | UTC_TIMESTAMP | SCHEMA + ) ('(' ')')? #simpleFunctionCall + | CONVERT '(' expression separator=',' convertedDataType ')' #dataTypeFunctionCall + | CONVERT '(' expression USING charsetName ')' #dataTypeFunctionCall + | CAST '(' expression AS convertedDataType ')' #dataTypeFunctionCall + | VALUES '(' fullColumnName ')' #valuesFunctionCall + | CASE expression caseFuncAlternative+ + (ELSE elseArg=functionArg)? END #caseExpressionFunctionCall + | CASE caseFuncAlternative+ + (ELSE elseArg=functionArg)? END #caseFunctionCall + | CHAR '(' functionArgs (USING charsetName)? ')' #charFunctionCall + | POSITION + '(' + ( + positionString=stringLiteral + | positionExpression=expression + ) + IN + ( + inString=stringLiteral + | inExpression=expression + ) + ')' #positionFunctionCall + | (SUBSTR | SUBSTRING) + '(' + ( + sourceString=stringLiteral + | sourceExpression=expression + ) FROM + ( + fromDecimal=decimalLiteral + | fromExpression=expression + ) + ( + FOR + ( + forDecimal=decimalLiteral + | forExpression=expression + ) + )? + ')' #substrFunctionCall + | TRIM + '(' + positioinForm=(BOTH | LEADING | TRAILING) + ( + sourceString=stringLiteral + | sourceExpression=expression + )? + FROM + ( + fromString=stringLiteral + | fromExpression=expression + ) + ')' #trimFunctionCall + | TRIM + '(' + ( + sourceString=stringLiteral + | sourceExpression=expression + ) + FROM + ( + fromString=stringLiteral + | fromExpression=expression + ) + ')' #trimFunctionCall + | WEIGHT_STRING + '(' + (stringLiteral | expression) + (AS stringFormat=(CHAR | BINARY) + '(' decimalLiteral ')' )? levelsInWeightString? + ')' #weightFunctionCall + | EXTRACT + '(' + intervalType + FROM + ( + sourceString=stringLiteral + | sourceExpression=expression + ) + ')' #extractFunctionCall + | GET_FORMAT + '(' + datetimeFormat=(DATE | TIME | DATETIME) + ',' stringLiteral + ')' #getFormatFunctionCall + | JSON_VALUE + '(' expression + ',' expression + (RETURNING convertedDataType)? + jsonOnEmpty? + jsonOnError? + ')' #jsonValueFunctionCall + ; + +caseFuncAlternative + : WHEN condition=functionArg + THEN consequent=functionArg + ; + +levelsInWeightString + : LEVEL levelInWeightListElement + (',' levelInWeightListElement)* #levelWeightList + | LEVEL + firstLevel=decimalLiteral '-' lastLevel=decimalLiteral #levelWeightRange + ; + +levelInWeightListElement + : decimalLiteral orderType=(ASC | DESC | REVERSE)? + ; + +aggregateWindowedFunction + : (AVG | MAX | MIN | SUM) + '(' aggregator=(ALL | DISTINCT)? functionArg ')' overClause? + | COUNT '(' (starArg='*' | aggregator=ALL? functionArg | aggregator=DISTINCT functionArgs) ')' overClause? + | ( + BIT_AND | BIT_OR | BIT_XOR | STD | STDDEV | STDDEV_POP + | STDDEV_SAMP | VAR_POP | VAR_SAMP | VARIANCE + ) '(' aggregator=ALL? functionArg ')' overClause? + | GROUP_CONCAT '(' + aggregator=DISTINCT? functionArgs + (ORDER BY + orderByExpression (',' orderByExpression)* + )? (SEPARATOR separator=STRING_LITERAL)? + ')' + ; + +nonAggregateWindowedFunction + : (LAG | LEAD) '(' expression (',' decimalLiteral)? (',' decimalLiteral)? ')' overClause + | (FIRST_VALUE | LAST_VALUE) '(' expression ')' overClause + | (CUME_DIST | DENSE_RANK | PERCENT_RANK | RANK | ROW_NUMBER) '('')' overClause + | NTH_VALUE '(' expression ',' decimalLiteral ')' overClause + | NTILE '(' decimalLiteral ')' overClause + ; + +overClause + : OVER ('(' windowSpec ')' | windowName) + ; + +windowSpec + : windowName? partitionClause? orderByClause? frameClause? + ; + +windowName + : uid + ; + +frameClause + : frameUnits frameExtent + ; + +frameUnits + : ROWS + | RANGE + ; + +frameExtent + : frameRange + | frameBetween + ; + +frameBetween + : BETWEEN frameRange AND frameRange + ; + +frameRange + : CURRENT ROW + | UNBOUNDED (PRECEDING | FOLLOWING) + | expression (PRECEDING | FOLLOWING) + ; + +partitionClause + : PARTITION BY expression (',' expression)* + ; + +scalarFunctionName + : functionNameBase + | ASCII | CURDATE | CURRENT_DATE | CURRENT_TIME + | CURRENT_TIMESTAMP | CURTIME | DATE_ADD | DATE_SUB + | IF | INSERT | LOCALTIME | LOCALTIMESTAMP | MID | NOW + | REPLACE | SUBSTR | SUBSTRING | SYSDATE | TRIM + | UTC_DATE | UTC_TIME | UTC_TIMESTAMP + ; + +passwordFunctionClause + : functionName=(PASSWORD | OLD_PASSWORD) '(' functionArg ')' + ; + +functionArgs + : (constant | fullColumnName | functionCall | expression) + ( + ',' + (constant | fullColumnName | functionCall | expression) + )* + ; + +functionArg + : constant | fullColumnName | functionCall | expression + ; + + +// Expressions, predicates + +// Simplified approach for expression +expression + : notOperator=(NOT | '!') expression #notExpression + | expression logicalOperator expression #logicalExpression + | predicate IS NOT? testValue=(TRUE | FALSE | UNKNOWN) #isExpression + | predicate #predicateExpression + ; + +predicate + : predicate NOT? IN '(' (selectStatement | expressions) ')' #inPredicate + | predicate IS nullNotnull #isNullPredicate + | left=predicate comparisonOperator right=predicate #binaryComparisonPredicate + | predicate comparisonOperator + quantifier=(ALL | ANY | SOME) '(' selectStatement ')' #subqueryComparisonPredicate + | predicate NOT? BETWEEN predicate AND predicate #betweenPredicate + | predicate SOUNDS LIKE predicate #soundsLikePredicate + | predicate NOT? LIKE predicate (ESCAPE STRING_LITERAL)? #likePredicate + | predicate NOT? regex=(REGEXP | RLIKE) predicate #regexpPredicate + | (LOCAL_ID VAR_ASSIGN)? expressionAtom #expressionAtomPredicate + | predicate MEMBER OF '(' predicate ')' #jsonMemberOfPredicate + ; + + +// Add in ASTVisitor nullNotnull in constant +expressionAtom + : constant #constantExpressionAtom + | fullColumnName #fullColumnNameExpressionAtom + | functionCall #functionCallExpressionAtom + | expressionAtom COLLATE collationName #collateExpressionAtom + | mysqlVariable #mysqlVariableExpressionAtom + | unaryOperator expressionAtom #unaryExpressionAtom + | BINARY expressionAtom #binaryExpressionAtom + | '(' expression (',' expression)* ')' #nestedExpressionAtom + | ROW '(' expression (',' expression)+ ')' #nestedRowExpressionAtom + | EXISTS '(' selectStatement ')' #existsExpressionAtom + | '(' selectStatement ')' #subqueryExpressionAtom + | INTERVAL expression intervalType #intervalExpressionAtom + | left=expressionAtom bitOperator right=expressionAtom #bitExpressionAtom + | left=expressionAtom mathOperator right=expressionAtom #mathExpressionAtom + | left=expressionAtom jsonOperator right=expressionAtom #jsonExpressionAtom + ; + +unaryOperator + : '!' | '~' | '+' | '-' | NOT + ; + +comparisonOperator + : '=' | '>' | '<' | '<' '=' | '>' '=' + | '<' '>' | '!' '=' | '<' '=' '>' + ; + +logicalOperator + : AND | '&' '&' | XOR | OR | '|' '|' + ; + +bitOperator + : '<' '<' | '>' '>' | '&' | '^' | '|' + ; + +mathOperator + : '*' | '/' | '%' | DIV | MOD | '+' | '-' + ; + +jsonOperator + : '-' '>' | '-' '>' '>' + ; + +// Simple id sets +// (that keyword, which can be id) + +charsetNameBase + : ARMSCII8 | ASCII | BIG5 | BINARY | CP1250 | CP1251 | CP1256 | CP1257 + | CP850 | CP852 | CP866 | CP932 | DEC8 | EUCJPMS | EUCKR + | GB18030 | GB2312 | GBK | GEOSTD8 | GREEK | HEBREW | HP8 | KEYBCS2 + | KOI8R | KOI8U | LATIN1 | LATIN2 | LATIN5 | LATIN7 | MACCE + | MACROMAN | SJIS | SWE7 | TIS620 | UCS2 | UJIS | UTF16 + | UTF16LE | UTF32 | UTF8 | UTF8MB3 | UTF8MB4 + ; + +transactionLevelBase + : REPEATABLE | COMMITTED | UNCOMMITTED | SERIALIZABLE + ; + +privilegesBase + : TABLES | ROUTINE | EXECUTE | FILE | PROCESS + | RELOAD | SHUTDOWN | SUPER | PRIVILEGES + ; + +intervalTypeBase + : QUARTER | MONTH | DAY | HOUR + | MINUTE | WEEK | SECOND | MICROSECOND + ; + +dataTypeBase + : DATE | TIME | TIMESTAMP | DATETIME | YEAR | ENUM | TEXT + ; + +keywordsCanBeId + : ACCOUNT | ACTION | ADMIN | AFTER | AGGREGATE | ALGORITHM | ANY + | AT | AUDIT_ADMIN | AUDIT_ABORT_EXEMPT | AUTHORS | AUTOCOMMIT | AUTOEXTEND_SIZE + | AUTO_INCREMENT | AUTHENTICATION_POLICY_ADMIN | AVG | AVG_ROW_LENGTH | ATTRIBUTE + | BACKUP_ADMIN | BEGIN | BINLOG | BINLOG_ADMIN | BINLOG_ENCRYPTION_ADMIN | BIT | BIT_AND | BIT_OR | BIT_XOR + | BLOCK | BOOL | BOOLEAN | BTREE | BUCKETS | CACHE | CASCADED | CHAIN | CHANGED + | CHANNEL | CHECKSUM | PAGE_CHECKSUM | CATALOG_NAME | CIPHER + | CLASS_ORIGIN | CLIENT | CLONE_ADMIN | CLOSE | CLUSTERING | COALESCE | CODE + | COLUMNS | COLUMN_FORMAT | COLUMN_NAME | COMMENT | COMMIT | COMPACT + | COMPLETION | COMPRESSED | COMPRESSION | CONCURRENT | CONDITION | CONNECT + | CONNECTION | CONNECTION_ADMIN | CONSISTENT | CONSTRAINT_CATALOG | CONSTRAINT_NAME + | CONSTRAINT_SCHEMA | CONTAINS | CONTEXT + | CONTRIBUTORS | COPY | COUNT | CPU | CURRENT | CURRENT_USER | CURSOR_NAME + | DATA | DATAFILE | DEALLOCATE + | DEFAULT | DEFAULT_AUTH | DEFINER | DELAY_KEY_WRITE | DES_KEY_FILE | DIAGNOSTICS | DIRECTORY + | DISABLE | DISCARD | DISK | DO | DUMPFILE | DUPLICATE + | DYNAMIC | EMPTY | ENABLE | ENCRYPTION | ENCRYPTION_KEY_ADMIN | END | ENDS | ENGINE | ENGINE_ATTRIBUTE | ENGINES | ENFORCED + | ERROR | ERRORS | ESCAPE | EUR | EVEN | EVENT | EVENTS | EVERY | EXCEPT + | EXCHANGE | EXCLUSIVE | EXPIRE | EXPORT | EXTENDED | EXTENT_SIZE | FAILED_LOGIN_ATTEMPTS | FAST | FAULTS + | FIELDS | FILE_BLOCK_SIZE | FILTER | FIREWALL_ADMIN | FIREWALL_EXEMPT | FIREWALL_USER | FIRST | FIXED | FLUSH + | FOLLOWS | FOUND | FULL | FUNCTION | GENERAL | GLOBAL | GRANTS | GROUP | GROUP_CONCAT + | GROUP_REPLICATION | GROUP_REPLICATION_ADMIN | HANDLER | HASH | HELP | HISTORY | HOST | HOSTS | IDENTIFIED + | IGNORED | IGNORE_SERVER_IDS | IMPORT | INDEXES | INITIAL_SIZE | INNODB_REDO_LOG_ARCHIVE + | INPLACE | INSERT_METHOD | INSTALL | INSTANCE | INSTANT | INTERNAL | INVOKE | INVOKER | IO + | IO_THREAD | IPC | ISO | ISOLATION | ISSUER | JIS | JSON | KEY_BLOCK_SIZE + | LAMBDA | LANGUAGE | LAST | LATERAL | LEAVES | LESS | LEVEL | LIST | LOCAL + | LOGFILE | LOGS | MASTER | MASTER_AUTO_POSITION + | MASTER_CONNECT_RETRY | MASTER_DELAY + | MASTER_HEARTBEAT_PERIOD | MASTER_HOST | MASTER_LOG_FILE + | MASTER_LOG_POS | MASTER_PASSWORD | MASTER_PORT + | MASTER_RETRY_COUNT | MASTER_SSL | MASTER_SSL_CA + | MASTER_SSL_CAPATH | MASTER_SSL_CERT | MASTER_SSL_CIPHER + | MASTER_SSL_CRL | MASTER_SSL_CRLPATH | MASTER_SSL_KEY + | MASTER_TLS_VERSION | MASTER_USER + | MAX_CONNECTIONS_PER_HOUR | MAX_QUERIES_PER_HOUR + | MAX | MAX_ROWS | MAX_SIZE | MAX_UPDATES_PER_HOUR + | MAX_USER_CONNECTIONS | MEDIUM | MEMBER | MEMORY | MERGE | MESSAGE_TEXT + | MID | MIGRATE + | MIN | MIN_ROWS | MODE | MODIFY | MUTEX | MYSQL | MYSQL_ERRNO | NAME | NAMES + | NCHAR | NDB_STORED_USER | NESTED | NEVER | NEXT | NO | NOCOPY | NODEGROUP | NONE | NOWAIT | NUMBER | ODBC | OFFLINE | OFFSET + | OF | OJ | OLD_PASSWORD | ONE | ONLINE | ONLY | OPEN | OPTIMIZER_COSTS + | OPTIONAL | OPTIONS | ORDER | ORDINALITY | OWNER | PACK_KEYS | PAGE | PARSER | PARTIAL + | PARTITIONING | PARTITIONS | PASSWORD | PASSWORDLESS_USER_ADMIN | PASSWORD_LOCK_TIME | PATH | PERSIST_RO_VARIABLES_ADMIN | PHASE | PLUGINS + | PLUGIN_DIR | PLUGIN | PORT | PRECEDES | PREPARE | PRESERVE | PREV | PRIMARY + | PROCESSLIST | PROFILE | PROFILES | PROXY | QUERY | QUICK + | REBUILD | RECOVER | RECURSIVE | REDO_BUFFER_SIZE | REDUNDANT + | RELAY | RELAYLOG | RELAY_LOG_FILE | RELAY_LOG_POS | REMOVE + | REORGANIZE | REPAIR | REPLICATE_DO_DB | REPLICATE_DO_TABLE + | REPLICATE_IGNORE_DB | REPLICATE_IGNORE_TABLE + | REPLICATE_REWRITE_DB | REPLICATE_WILD_DO_TABLE + | REPLICATE_WILD_IGNORE_TABLE | REPLICATION | REPLICATION_APPLIER | REPLICATION_SLAVE_ADMIN | RESET + | RESOURCE_GROUP_ADMIN | RESOURCE_GROUP_USER | RESUME + | RETURNED_SQLSTATE | RETURNS | REUSE | ROLE | ROLE_ADMIN | ROLLBACK | ROLLUP | ROTATE | ROW | ROWS + | ROW_FORMAT | RTREE | S3 | SAVEPOINT | SCHEDULE | SCHEMA_NAME | SECURITY | SECONDARY_ENGINE_ATTRIBUTE | SERIAL | SERVER + | SESSION | SESSION_VARIABLES_ADMIN | SET_USER_ID | SHARE | SHARED | SHOW_ROUTINE | SIGNED | SIMPLE | SLAVE + | SLOW | SKIP_QUERY_REWRITE | SNAPSHOT | SOCKET | SOME | SONAME | SOUNDS | SOURCE + | SQL_AFTER_GTIDS | SQL_AFTER_MTS_GAPS | SQL_BEFORE_GTIDS + | SQL_BUFFER_RESULT | SQL_CACHE | SQL_NO_CACHE | SQL_THREAD + | STACKED | START | STARTS | STATS_AUTO_RECALC | STATS_PERSISTENT + | STATS_SAMPLE_PAGES | STATUS | STD | STDDEV | STDDEV_POP | STDDEV_SAMP | STOP | STORAGE | STRING + | SUBCLASS_ORIGIN | SUBJECT | SUBPARTITION | SUBPARTITIONS | SUM | SUSPEND | SWAPS + | SWITCHES | SYSTEM_VARIABLES_ADMIN | TABLE_NAME | TABLESPACE | TABLE_ENCRYPTION_ADMIN | TABLE_TYPE + | TEMPORARY | TEMPTABLE | THAN | TP_CONNECTION_ADMIN | TRADITIONAL + | TRANSACTION | TRANSACTIONAL | TRIGGERS | TRUNCATE | UNBOUNDED | UNDEFINED | UNDOFILE + | UNDO_BUFFER_SIZE | UNINSTALL | UNKNOWN | UNTIL | UPGRADE | USA | USER | USE_FRM | USER_RESOURCES + | VALIDATION | VALUE | VAR_POP | VAR_SAMP | VARIABLES | VARIANCE | VERSION_TOKEN_ADMIN | VIEW | VIRTUAL + | WAIT | WARNINGS | WITHOUT | WORK | WRAPPER | X509 | XA | XA_RECOVER_ADMIN | XML + ; + +functionNameBase + : ABS | ACOS | ADDDATE | ADDTIME | AES_DECRYPT | AES_ENCRYPT + | AREA | ASBINARY | ASIN | ASTEXT | ASWKB | ASWKT + | ASYMMETRIC_DECRYPT | ASYMMETRIC_DERIVE + | ASYMMETRIC_ENCRYPT | ASYMMETRIC_SIGN | ASYMMETRIC_VERIFY + | ATAN | ATAN2 | BENCHMARK | BIN | BIT_COUNT | BIT_LENGTH + | BUFFER | CEIL | CEILING | CENTROID | CHARACTER_LENGTH + | CHARSET | CHAR_LENGTH | COERCIBILITY | COLLATION + | COMPRESS | CONCAT | CONCAT_WS | CONNECTION_ID | CONV + | CONVERT_TZ | COS | COT | COUNT | CRC32 + | CREATE_ASYMMETRIC_PRIV_KEY | CREATE_ASYMMETRIC_PUB_KEY + | CREATE_DH_PARAMETERS | CREATE_DIGEST | CROSSES | CUME_DIST | DATABASE | DATE + | DATEDIFF | DATE_FORMAT | DAY | DAYNAME | DAYOFMONTH + | DAYOFWEEK | DAYOFYEAR | DECODE | DEGREES | DENSE_RANK | DES_DECRYPT + | DES_ENCRYPT | DIMENSION | DISJOINT | ELT | ENCODE + | ENCRYPT | ENDPOINT | ENVELOPE | EQUALS | EXP | EXPORT_SET + | EXTERIORRING | EXTRACTVALUE | FIELD | FIND_IN_SET | FIRST_VALUE | FLOOR + | FORMAT | FOUND_ROWS | FROM_BASE64 | FROM_DAYS + | FROM_UNIXTIME | GEOMCOLLFROMTEXT | GEOMCOLLFROMWKB + | GEOMETRYCOLLECTION | GEOMETRYCOLLECTIONFROMTEXT + | GEOMETRYCOLLECTIONFROMWKB | GEOMETRYFROMTEXT + | GEOMETRYFROMWKB | GEOMETRYN | GEOMETRYTYPE | GEOMFROMTEXT + | GEOMFROMWKB | GET_FORMAT | GET_LOCK | GLENGTH | GREATEST + | GTID_SUBSET | GTID_SUBTRACT | HEX | HOUR | IFNULL + | INET6_ATON | INET6_NTOA | INET_ATON | INET_NTOA | INSTR + | INTERIORRINGN | INTERSECTS | INVISIBLE + | ISCLOSED | ISEMPTY | ISNULL + | ISSIMPLE | IS_FREE_LOCK | IS_IPV4 | IS_IPV4_COMPAT + | IS_IPV4_MAPPED | IS_IPV6 | IS_USED_LOCK | LAG | LAST_INSERT_ID | LAST_VALUE + | LCASE | LEAD | LEAST | LEFT | LENGTH | LINEFROMTEXT | LINEFROMWKB + | LINESTRING | LINESTRINGFROMTEXT | LINESTRINGFROMWKB | LN + | LOAD_FILE | LOCATE | LOG | LOG10 | LOG2 | LOWER | LPAD + | LTRIM | MAKEDATE | MAKETIME | MAKE_SET | MASTER_POS_WAIT + | MBRCONTAINS | MBRDISJOINT | MBREQUAL | MBRINTERSECTS + | MBROVERLAPS | MBRTOUCHES | MBRWITHIN | MD5 | MICROSECOND + | MINUTE | MLINEFROMTEXT | MLINEFROMWKB | MOD| MONTH | MONTHNAME + | MPOINTFROMTEXT | MPOINTFROMWKB | MPOLYFROMTEXT + | MPOLYFROMWKB | MULTILINESTRING | MULTILINESTRINGFROMTEXT + | MULTILINESTRINGFROMWKB | MULTIPOINT | MULTIPOINTFROMTEXT + | MULTIPOINTFROMWKB | MULTIPOLYGON | MULTIPOLYGONFROMTEXT + | MULTIPOLYGONFROMWKB | NAME_CONST | NTH_VALUE | NTILE | NULLIF | NUMGEOMETRIES + | NUMINTERIORRINGS | NUMPOINTS | OCT | OCTET_LENGTH | ORD + | OVERLAPS | PERCENT_RANK | PERIOD_ADD | PERIOD_DIFF | PI | POINT + | POINTFROMTEXT | POINTFROMWKB | POINTN | POLYFROMTEXT + | POLYFROMWKB | POLYGON | POLYGONFROMTEXT | POLYGONFROMWKB + | POSITION | POW | POWER | QUARTER | QUOTE | RADIANS | RAND | RANK + | RANDOM_BYTES | RELEASE_LOCK | REVERSE | RIGHT | ROUND + | ROW_COUNT | ROW_NUMBER | RPAD | RTRIM | SCHEMA | SECOND | SEC_TO_TIME + | SESSION_USER | SESSION_VARIABLES_ADMIN + | SHA | SHA1 | SHA2 | SIGN | SIN | SLEEP + | SOUNDEX | SQL_THREAD_WAIT_AFTER_GTIDS | SQRT | SRID + | STARTPOINT | STRCMP | STR_TO_DATE | ST_AREA | ST_ASBINARY + | ST_ASTEXT | ST_ASWKB | ST_ASWKT | ST_BUFFER | ST_CENTROID + | ST_CONTAINS | ST_CROSSES | ST_DIFFERENCE | ST_DIMENSION + | ST_DISJOINT | ST_DISTANCE | ST_ENDPOINT | ST_ENVELOPE + | ST_EQUALS | ST_EXTERIORRING | ST_GEOMCOLLFROMTEXT + | ST_GEOMCOLLFROMTXT | ST_GEOMCOLLFROMWKB + | ST_GEOMETRYCOLLECTIONFROMTEXT + | ST_GEOMETRYCOLLECTIONFROMWKB | ST_GEOMETRYFROMTEXT + | ST_GEOMETRYFROMWKB | ST_GEOMETRYN | ST_GEOMETRYTYPE + | ST_GEOMFROMTEXT | ST_GEOMFROMWKB | ST_INTERIORRINGN + | ST_INTERSECTION | ST_INTERSECTS | ST_ISCLOSED | ST_ISEMPTY + | ST_ISSIMPLE | ST_LINEFROMTEXT | ST_LINEFROMWKB + | ST_LINESTRINGFROMTEXT | ST_LINESTRINGFROMWKB + | ST_NUMGEOMETRIES | ST_NUMINTERIORRING + | ST_NUMINTERIORRINGS | ST_NUMPOINTS | ST_OVERLAPS + | ST_POINTFROMTEXT | ST_POINTFROMWKB | ST_POINTN + | ST_POLYFROMTEXT | ST_POLYFROMWKB | ST_POLYGONFROMTEXT + | ST_POLYGONFROMWKB | ST_SRID | ST_STARTPOINT + | ST_SYMDIFFERENCE | ST_TOUCHES | ST_UNION | ST_WITHIN + | ST_X | ST_Y | SUBDATE | SUBSTRING_INDEX | SUBTIME + | SYSTEM_USER | TAN | TIME | TIMEDIFF | TIMESTAMP + | TIMESTAMPADD | TIMESTAMPDIFF | TIME_FORMAT | TIME_TO_SEC + | TOUCHES | TO_BASE64 | TO_DAYS | TO_SECONDS | UCASE + | UNCOMPRESS | UNCOMPRESSED_LENGTH | UNHEX | UNIX_TIMESTAMP + | UPDATEXML | UPPER | UUID | UUID_SHORT + | VALIDATE_PASSWORD_STRENGTH | VERSION | VISIBLE + | WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS | WEEK | WEEKDAY + | WEEKOFYEAR | WEIGHT_STRING | WITHIN | YEAR | YEARWEEK + | Y_FUNCTION | X_FUNCTION + | JSON_ARRAY | JSON_OBJECT | JSON_QUOTE | JSON_CONTAINS | JSON_CONTAINS_PATH + | JSON_EXTRACT | JSON_KEYS | JSON_OVERLAPS | JSON_SEARCH | JSON_VALUE + | JSON_ARRAY_APPEND | JSON_ARRAY_INSERT | JSON_INSERT | JSON_MERGE + | JSON_MERGE_PATCH | JSON_MERGE_PRESERVE | JSON_REMOVE | JSON_REPLACE + | JSON_SET | JSON_UNQUOTE | JSON_DEPTH | JSON_LENGTH | JSON_TYPE + | JSON_VALID | JSON_TABLE | JSON_SCHEMA_VALID | JSON_SCHEMA_VALIDATION_REPORT + | JSON_PRETTY | JSON_STORAGE_FREE | JSON_STORAGE_SIZE | JSON_ARRAYAGG + | JSON_OBJECTAGG + ; diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/AbstractPartition.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/AbstractPartition.java new file mode 100644 index 0000000000..4ddbf28be4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/AbstractPartition.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.connector.jdbc; + +public abstract class AbstractPartition implements Partition { + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/CatalogChanges.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/CatalogChanges.java new file mode 100644 index 0000000000..34d2554f65 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/CatalogChanges.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.connector.jdbc; + +import org.apache.eventmesh.connector.jdbc.event.SchemaChangeEventType; +import org.apache.eventmesh.connector.jdbc.table.catalog.CatalogSchema; +import org.apache.eventmesh.connector.jdbc.table.catalog.Column; +import org.apache.eventmesh.connector.jdbc.table.catalog.Table; + +import java.util.List; + +import lombok.Data; + +@Data +/** + * Represents changes in a catalog, such as schema or table modifications. + */ +public class CatalogChanges { + + /** + * The type of change (e.g., "T(Table)" or "D(Database)"). + * + * {@link SchemaChangeEventType} + * + */ + private String type; + + /** + * The specific operation type (e.g., "C(Create)", "D(Drop)", "A(Alert)"). + * + * {@link SchemaChangeEventType} + * + */ + private String operationType; + // The catalog schema associated with the changes + private CatalogSchema catalog; + // The table associated with the changes + private Table table; + // The list of columns affected by the changes + private List columns; + + private CatalogChanges(String type, String operationType, CatalogSchema catalog, Table table, + List columns) { + this.type = type; + this.operationType = operationType; + this.catalog = catalog; + this.table = table; + this.columns = columns; + } + + /** + * Creates a new instance of the Builder for constructing CatalogChanges. + * + * @return The Builder instance. + */ + public static Builder newBuilder() { + return new Builder(); + } + + /** + * Builder class for constructing CatalogChanges. + */ + public static class Builder { + + private String type; + private String operationType; + private CatalogSchema catalog; + private Table table; + private List columns; + + /** + * Sets the operation type for the change. + * + * @param changeEventType The SchemaChangeEventType representing the change. + * @return The Builder instance. + */ + public Builder operationType(SchemaChangeEventType changeEventType) { + this.type = changeEventType.ofType(); + this.operationType = changeEventType.ofOperationType(); + return this; + } + + /** + * Sets the catalog schema associated with the changes. + * + * @param catalog The CatalogSchema instance. + * @return The Builder instance. + */ + public Builder catalog(CatalogSchema catalog) { + this.catalog = catalog; + return this; + } + + /** + * Sets the table associated with the changes. + * + * @param table The Table instance. + * @return The Builder instance. + */ + public Builder table(Table table) { + this.table = table; + return this; + } + + /** + * Sets the list of columns affected by the changes. + * + * @param columns The list of Column instances. + * @return The Builder instance. + */ + public Builder columns(List columns) { + this.columns = columns; + return this; + } + + /** + * Builds a new CatalogChanges instance. + * + * @return The constructed CatalogChanges instance. + */ + public CatalogChanges build() { + return new CatalogChanges(type, operationType, catalog, table, columns); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/DataChanges.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/DataChanges.java new file mode 100644 index 0000000000..cb0298e91f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/DataChanges.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.jdbc; + +import lombok.Data; + +@Data +public class DataChanges { + + private Object after; + + private Object before; + + private String type; + + public DataChanges(Object after, Object before) { + this.after = after; + this.before = before; + } + + public DataChanges(Object after, Object before, String type) { + this.after = after; + this.before = before; + this.type = type; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private String type; + private Object after; + private Object before; + + public Builder withType(String type) { + this.type = type; + return this; + } + + public Builder withAfter(Object after) { + this.after = after; + return this; + } + + public Builder withBefore(Object before) { + this.before = before; + return this; + } + + public DataChanges build() { + return new DataChanges(after, before, type); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/DataTypeConvertor.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/DataTypeConvertor.java new file mode 100644 index 0000000000..61b1e2749a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/DataTypeConvertor.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.connector.jdbc; + +import org.apache.eventmesh.connector.jdbc.exception.DataTypeConvertException; +import org.apache.eventmesh.connector.jdbc.table.type.EventMeshDataType; + +import java.sql.JDBCType; +import java.util.Map; + +/** + * convert data types between EventMesh and connector. + */ +public interface DataTypeConvertor { + + /** + * Converts a string representation of a connector data type to the corresponding JDBCType. + * + * @param connectorDataType The string representation of the connector data type. + * @return The corresponding JDBCType, or null if the connector data type is not recognized. + */ + JDBCType toJDBCType(String connectorDataType); + + /** + * Converts a connector data type to an EventMesh data type. + * + * @param connectorDataType The connector data type to be converted. + * @return The converted EventMesh data type. + * @throws DataTypeConvertException If the conversion fails. + */ + EventMeshDataType toEventMeshType(String connectorDataType) throws DataTypeConvertException; + + /** + * Converts JDBCType and dataTypeProperties to EventMeshDataType. + * + * @param jdbcType the JDBCType to be converted + * @param dataTypeProperties the properties of the data type + * @return the converted EventMeshDataType + * @throws DataTypeConvertException if there is an error during conversion + */ + EventMeshDataType toEventMeshType(JDBCType jdbcType, Map dataTypeProperties) throws DataTypeConvertException; + + /** + * Converts a connector data type to an EventMesh data type with additional data type properties. + * + * @param connectorDataType The connector data type to be converted. + * @param dataTypeProperties Additional data type properties. + * @return The converted EventMesh data type. + * @throws DataTypeConvertException If the conversion fails. + */ + EventMeshDataType toEventMeshType(T connectorDataType, Map dataTypeProperties) throws DataTypeConvertException; + + /** + * Converts an EventMesh data type to a connector data type with additional data type properties. + * + * @param eventMeshDataType The EventMesh data type to be converted. + * @param dataTypeProperties Additional data type properties. + * @return The converted connector data type. + * @throws DataTypeConvertException If the conversion fails. + */ + T toConnectorType(EventMeshDataType eventMeshDataType, Map dataTypeProperties) throws DataTypeConvertException; +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/DatabaseDialect.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/DatabaseDialect.java new file mode 100644 index 0000000000..11378270a4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/DatabaseDialect.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.jdbc; + +import org.apache.eventmesh.connector.jdbc.connection.JdbcConnection; +import org.apache.eventmesh.connector.jdbc.connection.JdbcConnectionProvider; +import org.apache.eventmesh.connector.jdbc.table.catalog.Catalog; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +/** + * Interface for a database dialect, which extends the ConnectionProvider and Catalog interfaces. + */ +public interface DatabaseDialect extends JdbcConnectionProvider, Catalog { + + /** + * Initializes the database dialect. + */ + void init(); + + /** + * Starts the database dialect. + */ + void start(); + + /** + * Retrieves the name of the database dialect. + * + * @return The name of the database dialect. + */ + String getName(); + + /** + * Creates a prepared statement for the given SQL query using the provided database connection. + * + * @param connection The database connection. + * @param sql The SQL query. + * @return The prepared statement. + * @throws SQLException If an error occurs while creating the prepared statement. + */ + PreparedStatement createPreparedStatement(Connection connection, String sql) throws SQLException; + + /** + * Retrieves the JDBC driver meta-data associated with the database dialect. + * + * @return The JDBC driver meta-data. + */ + JdbcDriverMetaData getJdbcDriverMetaData(); + + /** + * Retrieves the JDBC protocol associated with the database dialect. + * + * @return The JDBC protocol. + */ + String jdbcProtocol(); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Field.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Field.java new file mode 100644 index 0000000000..66d583de73 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Field.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.jdbc; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Field { + + private String type; + + private boolean required; + + private String field; + + private String name; + + private List fields; + + public Field(String type, boolean required, String field, String name) { + this.type = type; + this.required = required; + this.field = field; + this.name = name; + } + + public Field withType(String type) { + this.type = type; + return this; + } + + public Field withRequired(boolean required) { + this.required = required; + return this; + } + + public Field withField(String field) { + this.field = field; + return this; + } + + public Field withName(String name) { + this.name = name; + return this; + } + + public Field withFields(List fields) { + this.fields = fields; + return this; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/JdbcConnectData.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/JdbcConnectData.java new file mode 100644 index 0000000000..3dca4f42f4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/JdbcConnectData.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.jdbc; + +public final class JdbcConnectData { + + public static final byte DATA_CHANGES = 1; + + public static final byte SCHEMA_CHANGES = 1 << 1; + + private Payload payload = new Payload(); + + private Schema schema; + + private byte type; + + public JdbcConnectData() { + } + + public JdbcConnectData(byte type) { + this.type = type; + } + + public Payload getPayload() { + return payload; + } + + public void setPayload(Payload payload) { + this.payload = payload; + } + + public Schema getSchema() { + return schema; + } + + public void setSchema(Schema schema) { + this.schema = schema; + } + + public byte getType() { + return type; + } + + public void setType(byte type) { + this.type = type; + } + + public void markDataChanges() { + this.type |= DATA_CHANGES; + } + + public void markSchemaChanges() { + this.type |= SCHEMA_CHANGES; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/JdbcContext.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/JdbcContext.java new file mode 100644 index 0000000000..1c6eeb58b8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/JdbcContext.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.jdbc; + +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +/** + * Interface representing a JDBC context. + */ +public interface JdbcContext { + + Part getPartition(); + + OffSetCtx getOffsetContext(); + + TableId ofCurrentTableId(); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/JdbcDriverMetaData.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/JdbcDriverMetaData.java new file mode 100644 index 0000000000..fdc1e0fcde --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/JdbcDriverMetaData.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.connector.jdbc; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.ToString; + +/** + * Represents metadata information about a JDBC driver + */ +@Data +@AllArgsConstructor +@ToString +public class JdbcDriverMetaData { + + // The major version number of the JDBC driver + private final int jdbcMajorVersion; + + // The minor version number of the JDBC driver + private final int jdbcMinorVersion; + + // The name of the JDBC driver + private final String jdbcDriverName; + + // The name of the database product + private final String databaseProductName; + + // The version of the database product + private final String databaseProductVersion; + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/OffsetContext.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/OffsetContext.java new file mode 100644 index 0000000000..a74af0259c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/OffsetContext.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.connector.jdbc; + +import java.util.Map; + +/** + * The OffsetContext interface represents the offset context for event processing. It provides methods to retrieve the offset map and check if a + * snapshot is currently running. + */ +public interface OffsetContext { + + /** + * Retrieves the offset map associated with the context. + * + * @return The offset map. + */ + Map getOffset(); + + /** + * Checks if a snapshot is currently running. + * + * @return True if a snapshot is running, false otherwise. + */ + boolean isSnapshotRunning(); + + boolean isSnapshotCompleted(); + + void markSnapshotRunning(); + + void markSnapshotCompleted(); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Partition.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Partition.java new file mode 100644 index 0000000000..e1394a4f7c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Partition.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.jdbc; + +import java.util.Map; + +/** + * This interface represents a partition. + */ +public interface Partition { + + /** + *

Returns a map representing the partition.The keys of the map represent the partition keys, and the values represent the corresponding + * partition values.

+ * + * @return a map representing the partition + */ + Map getPartition(); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/PartitionOffSetContextPair.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/PartitionOffSetContextPair.java new file mode 100644 index 0000000000..30ec03d111 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/PartitionOffSetContextPair.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.connector.jdbc; + +public final class PartitionOffSetContextPair { + + private Part partition; + + private Offset offsetContext; + + private PartitionOffSetContextPair(Part partition, Offset offsetContext) { + this.partition = partition; + this.offsetContext = offsetContext; + } + + public static PartitionOffSetContextPair of(Part partition, Offset offset) { + return new PartitionOffSetContextPair<>(partition, offset); + } + + public Part getPartition() { + return partition; + } + + public Offset getOffsetContext() { + return offsetContext; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Payload.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Payload.java new file mode 100644 index 0000000000..f9b66d3d53 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Payload.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.connector.jdbc; + +import org.apache.eventmesh.connector.jdbc.source.SourceMateData; + +import java.util.HashMap; + +public final class Payload extends HashMap { + + public static final String AFTER_FIELD = "after"; + + public static final String BEFORE_FIELD = "before"; + + public static final String SOURCE = "source"; + + public static final String DDL = "ddl"; + + /** + * Constructs an empty HashMap with the default initial capacity (16) and the default load factor (0.75). + */ + public Payload() { + this.put("timestamp", System.currentTimeMillis()); + } + + public Payload withSource(SourceMateData source) { + this.put(SOURCE, source); + return this; + } + + public Payload withDdl(String ddl) { + this.put(DDL, ddl); + return this; + } + + public Payload withCatalogChanges(CatalogChanges catalogChanges) { + this.put("catalogChanges", catalogChanges); + return this; + } + + public Payload withDataChanges(DataChanges dataChanges) { + this.put("dataChanges", dataChanges); + return this; + } + + public SourceMateData ofSourceMateData() { + return (SourceMateData) super.get(SOURCE); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private final Payload payload; + + private Builder() { + payload = new Payload(); + } + + public Builder put(String key, Object value) { + payload.put(key, value); + return this; + } + + public Builder withSource(SourceMateData source) { + payload.put(SOURCE, source); + return this; + } + + public Payload build() { + return payload; + } + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Schema.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Schema.java new file mode 100644 index 0000000000..084f9759bc --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/Schema.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.connector.jdbc; + +import java.util.ArrayList; +import java.util.List; + +import lombok.Data; + +@Data +public class Schema { + + private List fields; + + public Schema(List fields) { + this.fields = fields; + } + + public Schema() { + this.fields = new ArrayList<>(); + } + + public void add(Field field) { + this.fields.add(field); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/UniversalJdbcContext.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/UniversalJdbcContext.java new file mode 100644 index 0000000000..af89638149 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/UniversalJdbcContext.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.connector.jdbc; + +import org.apache.eventmesh.connector.jdbc.ddl.DdlParser; +import org.apache.eventmesh.connector.jdbc.table.catalog.CatalogTableSet; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public abstract class UniversalJdbcContext implements + JdbcContext { + + private PartitionOffSetContextPair poCtx; + + private Parser parser; + + private CatalogTableSet tableSet = new CatalogTableSet(); + + private volatile TableId tableId; + + public UniversalJdbcContext(PartitionOffSetContextPair poCtx, Parser parser) { + this.poCtx = poCtx; + this.parser = parser; + } + + public UniversalJdbcContext(Part part, OffSetCtx offSetCtx, Parser parser) { + this.poCtx = PartitionOffSetContextPair.of(part, offSetCtx); + this.parser = parser; + } + + @Override + public Part getPartition() { + return poCtx.getPartition(); + } + + @Override + public OffSetCtx getOffsetContext() { + return poCtx.getOffsetContext(); + } + + /** + * @return + */ + @Override + public TableId ofCurrentTableId() { + return tableId; + } + + public Parser getParser() { + return parser; + } + + public CatalogTableSet getCatalogTableSet() { + return this.tableSet; + } + + public void withTableId(TableId tableId) { + this.tableId = tableId; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/UniversalOffsetContext.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/UniversalOffsetContext.java new file mode 100644 index 0000000000..baa7ba3554 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/UniversalOffsetContext.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.connector.jdbc; + +public abstract class UniversalOffsetContext implements OffsetContext { + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/antlr4/Antlr4DdlParser.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/antlr4/Antlr4DdlParser.java new file mode 100644 index 0000000000..61e79eede2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/antlr4/Antlr4DdlParser.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.connector.jdbc.antlr4; + +import org.apache.eventmesh.connector.jdbc.antlr4.listener.Antlr4DdlParserListener; +import org.apache.eventmesh.connector.jdbc.ddl.AbstractDdlParser; +import org.apache.eventmesh.connector.jdbc.ddl.DdlParserCallback; +import org.apache.eventmesh.connector.jdbc.table.catalog.CatalogTableSet; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CodePointCharStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.ParseTreeWalker; + +public abstract class Antlr4DdlParser extends AbstractDdlParser { + + private Antlr4DdlParserListener antlr4DdlParserListener; + + private CatalogTableSet tableSet; + + public Antlr4DdlParser(boolean skipViews, boolean skipComments) { + super(skipViews, skipComments); + } + + /** + * Parses the given DDL SQL statement. + * + * @param ddlSql the DDL SQL statement to be parsed + */ + @Override + public void parse(String ddlSql, DdlParserCallback callback) { + CodePointCharStream ddlSqlStream = CharStreams.fromString(ddlSql); + L lexer = buildLexerInstance(ddlSqlStream); + P parser = buildParserInstance(new CommonTokenStream(lexer)); + ParseTree parseTree = parseTree(parser); + antlr4DdlParserListener = createParseTreeWalkerListener(callback); + ParseTreeWalker.DEFAULT.walk(antlr4DdlParserListener, parseTree); + } + + protected abstract L buildLexerInstance(CharStream charStreams); + + protected abstract P buildParserInstance(CommonTokenStream commonTokenStream); + + protected abstract ParseTree parseTree(P parser); + + protected abstract Antlr4DdlParserListener createParseTreeWalkerListener(DdlParserCallback callback); + + public void setCatalogTableSet(CatalogTableSet tableSet) { + this.tableSet = tableSet; + } + + public CatalogTableSet getCatalogTableSet() { + return this.tableSet; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/antlr4/listener/Antlr4DdlParserListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/antlr4/listener/Antlr4DdlParserListener.java new file mode 100644 index 0000000000..d4128324f8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/antlr4/listener/Antlr4DdlParserListener.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.connector.jdbc.antlr4.listener; + +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * An interface to extend the Antlr4 {@link ParseTreeListener} for DDL parsing events. + */ +public interface Antlr4DdlParserListener extends ParseTreeListener { + + // You can add any specific methods related to DDL parsing events here, + // if necessary. + +} + diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/common/SourceInfo.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/common/SourceInfo.java new file mode 100644 index 0000000000..0bbe0354b9 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/common/SourceInfo.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.connector.jdbc.common; + +/** + * Interface representing source information. + */ +public interface SourceInfo { + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/config/JdbcConfig.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/config/JdbcConfig.java new file mode 100644 index 0000000000..9c7558426c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/config/JdbcConfig.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.connector.jdbc.config; + +import java.util.Properties; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Represents the configuration for a JDBC connection. + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +public class JdbcConfig { + + private String databaseName; + + // The hostname of the database server. + private String hostname; + + // The port number of the database server. + private int port; + + // The username for the database connection. + private String user; + + // The password for the database connection. + private String password; + + private String initialStatements; + + private int connectTimeout; + + /** + * Converts the JdbcConfig object to a Properties object containing the user and password. + * + * @return The Properties object representing the JdbcConfig. + */ + public Properties asProperties() { + Properties props = new Properties(); + props.put("user", this.user); + props.put("password", this.password); + return props; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/config/JdbcServerConfig.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/config/JdbcServerConfig.java new file mode 100644 index 0000000000..451ecf71e9 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/config/JdbcServerConfig.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.connector.jdbc.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * configuration for the JDBC server. + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class JdbcServerConfig extends Config { + + // Indicates whether the source is enabled or not + private boolean sourceEnable; + + // Indicates whether the sink is enabled or not + private boolean sinkEnable; + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/JdbcConnection.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/JdbcConnection.java new file mode 100644 index 0000000000..78ddcad8e4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/JdbcConnection.java @@ -0,0 +1,577 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.connection; + +import org.apache.eventmesh.connector.jdbc.JdbcDriverMetaData; +import org.apache.eventmesh.connector.jdbc.config.JdbcConfig; + +import org.apache.commons.lang3.StringUtils; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.annotation.concurrent.ThreadSafe; + +import lombok.extern.slf4j.Slf4j; + +/** + * JdbcConnection class representing a JDBC connection. + * Implements the AutoCloseable interface. + */ +@Slf4j +public class JdbcConnection implements AutoCloseable { + + private static final int CONNECTION_VALID_CHECK_TIMEOUT_IN_SEC = 3; + + private static final String STATEMENT_DELIMITER = ";"; + + private final JdbcConfig jdbcConfig; + + private volatile Connection connection; + + private final InitialOperation initialOperation; + + private final ConnectionFactory connectionFactory; + + private JdbcDriverMetaData jdbcDriverMetaData; + + private boolean lazyConnection = true; + + public JdbcConnection(JdbcConfig jdbcConfig, InitialOperation initialOperation, ConnectionFactory connectionFactory) { + this(jdbcConfig, initialOperation, connectionFactory, true); + } + + public JdbcConnection(JdbcConfig jdbcConfig, InitialOperation initialOperation, ConnectionFactory connectionFactory, boolean lazyConnection) { + this.jdbcConfig = jdbcConfig; + this.initialOperation = initialOperation; + this.connectionFactory = connectionFactory; + this.lazyConnection = lazyConnection; + if (!this.lazyConnection) { + try { + connection(); + } catch (SQLException e) { + log.warn("Get Connection error", e); + throw new RuntimeException(e); + } + } + } + + /** + * Closes the JDBC connection. + * + * @throws Exception if an error occurs while closing the connection. + */ + @Override + public void close() throws Exception { + if (connection != null) { + connection.close(); + } + } + + /** + * Retrieves the JDBC configuration. + * + * @return The JDBC configuration. + */ + public JdbcConfig getJdbcConfig() { + return jdbcConfig; + } + + /** + * Sets the auto-commit mode for the connection. + * + * @param autoCommit The auto-commit mode. + * @return The JdbcConnection instance. + * @throws SQLException if a database access error occurs. + */ + public JdbcConnection setAutoCommit(boolean autoCommit) throws SQLException { + connection().setAutoCommit(autoCommit); + return this; + } + + /** + * Retrieves the JDBC connection. Creates a new connection if not already connected. + * + * @return The JDBC connection. + * @throws SQLException if a database access error occurs. + */ + public synchronized Connection connection() throws SQLException { + return connection(true); + } + + /** + * Retrieves the JDBC connection. Creates a new connection if not already connected. + * + * @param executeOnConnect Flag indicating whether to execute initial statements on connect. + * @return The JDBC connection. + * @throws SQLException if a database access error occurs. + */ + public synchronized Connection connection(boolean executeOnConnect) throws SQLException { + if (!isConnected()) { + connection = connectionFactory.connect(jdbcConfig); + if (!isConnected()) { + throw new SQLException("Unable to obtain a JDBC connection"); + } + + if (initialOperation != null) { + execute(initialOperation); + } + final String statements = jdbcConfig.getInitialStatements(); + if (StringUtils.isNotBlank(statements) && executeOnConnect) { + String[] split = statements.split(STATEMENT_DELIMITER); + execute(split); + } + jdbcDriverMetaData = createJdbcDriverInfo(); + } + return connection; + } + + /** + * Creates the JDBC driver metadata by retrieving information from the provided connection's database metadata. + * + * @return The JDBC driver metadata. + * @throws SQLException if a database access error occurs. + */ + private JdbcDriverMetaData createJdbcDriverInfo() throws SQLException { + DatabaseMetaData metadata = connection.getMetaData(); + + // Retrieve the JDBC driver information from the database metadata + int majorVersion = metadata.getJDBCMajorVersion(); + int minorVersion = metadata.getJDBCMinorVersion(); + String driverName = metadata.getDriverName(); + String productName = metadata.getDatabaseProductName(); + String productVersion = metadata.getDatabaseProductVersion(); + + // Create and return the JdbcDriverMetaData instance + return new JdbcDriverMetaData(majorVersion, minorVersion, driverName, productName, productVersion); + } + + public JdbcDriverMetaData getJdbcDriverMetaData() { + return jdbcDriverMetaData; + } + + /** + * Executes SQL statements on the JDBC connection. + * + * @param sqlStatements The SQL statements to execute. + * @return The JdbcConnection instance. + * @throws SQLException if a database access error occurs. + */ + public JdbcConnection execute(String... sqlStatements) throws SQLException { + return execute(statement -> { + for (String sqlStatement : sqlStatements) { + if (sqlStatement != null) { + log.debug("Executing '{}'", sqlStatement); + statement.execute(sqlStatement); + } + } + }); + } + + /** + * Executes a custom initial operation on the JDBC connection. + * + * @param operation The initial operation to execute. + * @return The JdbcConnection instance. + * @throws SQLException if a database access error occurs. + */ + public JdbcConnection execute(InitialOperation operation) throws SQLException { + Connection conn = connection(); + try (Statement statement = conn.createStatement()) { + operation.apply(statement); + commit(); + } + return this; + } + + /** + * Execute the given SQL statements without committing the changes. + * + * @param sqlStatements The SQL statements to execute + * @return This JdbcConnection instance + * @throws SQLException If an SQL error occurs + */ + public JdbcConnection executeWithoutCommitting(String... sqlStatements) throws SQLException { + Connection conn = connection(); + if (conn.getAutoCommit()) { + throw new SQLException("Cannot execute without committing because auto-commit is enabled"); + } + + try (Statement statement = conn.createStatement()) { + for (String sqlStatement : sqlStatements) { + log.debug("Executing sql statement: {}", sqlStatement); + statement.execute(sqlStatement); + } + } + + return this; + } + + /** + * Checks if the JDBC connection is connected. + * + * @return true if the connection is connected, false otherwise. + * @throws SQLException if a database access error occurs. + */ + public synchronized boolean isConnected() throws SQLException { + if (connection == null) { + return false; + } + return !connection.isClosed(); + } + + /** + * Checks if the JDBC connection is valid. + * + * @return true if the connection is valid, false otherwise. + * @throws SQLException if a database access error occurs. + */ + public synchronized boolean isValid() throws SQLException { + return isConnected() && connection.isValid(CONNECTION_VALID_CHECK_TIMEOUT_IN_SEC); + } + + /** + * Commits the changes on the JDBC connection. + * + * @return The JdbcConnection instance. + * @throws SQLException if a database access error occurs. + */ + public JdbcConnection commit() throws SQLException { + Connection conn = connection(); + if (!conn.getAutoCommit()) { + conn.commit(); + } + return this; + } + + /** + * Executes a query on the JDBC connection and consumes the result set using the provided consumer. + * + * @param sql The SQL query to execute. + * @param resultConsumer The consumer to process the result set. + * @return The JdbcConnection instance. + * @throws SQLException if a database access error occurs. + */ + public JdbcConnection query(String sql, JdbcResultSetConsumer resultConsumer) throws SQLException { + // Check if the connection is connected and valid + if (isConnected() && isValid()) { + connection(); + } + return query(sql, Connection::createStatement, resultConsumer); + } + + /** + * Executes a query on the JDBC connection and consumes the result set using the provided consumer. + * + * @param sql The SQL query to execute. + * @param statementFactory The factory to create the statement. + * @param resultConsumer The consumer to process the result set. + * @return The JdbcConnection instance. + * @throws SQLException if a database access error occurs. + */ + public JdbcConnection query(String sql, StatementFactory statementFactory, JdbcResultSetConsumer resultConsumer) throws SQLException { + Connection conn = connection(); + try (Statement statement = statementFactory.createStatement(conn)) { + log.debug("Query sql '{}'", sql); + try (ResultSet resultSet = statement.executeQuery(sql)) { + if (resultConsumer != null) { + resultConsumer.accept(resultSet); + } + } + } + return this; + } + + /** + * Executes a query on the JDBC connection and maps the result set using the provided ResultSetMapper. + * + * @param sql The SQL query to execute. + * @param resultSetMapper The mapper to map the result set to an object. + * @return The mapped object. + * @throws SQLException if a database access error occurs. + */ + public T query(String sql, ResultSetMapper resultSetMapper) throws SQLException { + // Check if the connection is connected and valid + if (isConnected() && isValid()) { + connection(); + } + return query(sql, Connection::createStatement, resultSetMapper); + } + + /** + * Executes a query on the JDBC connection and maps the result set using the provided ResultSetMapper. + * + * @param sql The SQL query to execute. + * @param statementFactory The factory to create the statement. + * @param resultSetMapper The mapper to map the result set to an object. + * @return The mapped object. + * @throws SQLException if a database access error occurs. + */ + public T query(String sql, StatementFactory statementFactory, ResultSetMapper resultSetMapper) throws SQLException { + Connection conn = connection(); + try (Statement statement = statementFactory.createStatement(conn)) { + log.debug("Query sql '{}'", sql); + try (ResultSet resultSet = statement.executeQuery(sql)) { + if (resultSetMapper != null) { + return resultSetMapper.map(resultSet); + } + } + } + return null; + } + + /** + * Executes a prepared query on the JDBC connection and consumes the result set using the provided consumer. + * + * @param sql The SQL query to execute. + * @param resultConsumer The consumer to process the result set. + * @param preparedParameters The prepared parameters for the query. + * @return The JdbcConnection instance. + * @throws SQLException if a database access error occurs. + */ + public JdbcConnection preparedQuery(String sql, JdbcResultSetConsumer resultConsumer, PreparedParameter... preparedParameters) + throws SQLException { + // Check if the connection is connected and valid + if (isConnected() && isValid()) { + connection(); + } + return preparedQuery(sql, (conn, statement) -> conn.prepareStatement(sql), resultConsumer, preparedParameters); + } + + /** + * Executes a prepared query on the JDBC connection and consumes the result set using the provided consumer. + * + * @param sql The SQL query to execute. + * @param preparedStatementFactory The factory to create the prepared statement. + * @param resultConsumer The consumer to process the result set. + * @param preparedParameters The prepared parameters for the query. + * @return The JdbcConnection instance. + * @throws SQLException if a database access error occurs. + */ + public JdbcConnection preparedQuery(String sql, PreparedStatementFactory preparedStatementFactory, JdbcResultSetConsumer resultConsumer, + PreparedParameter... preparedParameters) throws SQLException { + + Connection conn = connection(); + try (PreparedStatement preparedStatement = preparedStatementFactory.createPreparedStatement(conn, sql)) { + log.debug("Query sql '{}'", sql); + if (preparedParameters != null) { + for (int index = 0; index < preparedParameters.length; ++index) { + final PreparedParameter preparedParameter = preparedParameters[index]; + if (preparedParameter.getJdbcType() == null) { + preparedStatement.setObject(index + 1, preparedParameter.getValue()); + } else { + preparedStatement.setObject(index + 1, preparedParameter.getValue(), preparedParameter.getJdbcType().getVendorTypeNumber()); + } + } + } + try (ResultSet resultSet = preparedStatement.executeQuery()) { + if (resultConsumer != null) { + resultConsumer.accept(resultSet); + } + } + } + return this; + } + + /** + * Executes a prepared query on the JDBC connection and maps the result set using the provided ResultSetMapper. + * + * @param sql The SQL query to execute. + * @param resultSetMapper The mapper to map the result set to an object. + * @param preparedParameters The prepared parameters for the query. + * @return The mapped object. + * @throws SQLException if a database access error occurs. + */ + public T preparedQuery(String sql, ResultSetMapper resultSetMapper, PreparedParameter... preparedParameters) + throws SQLException { + // Check if the connection is connected and valid + if (isConnected() && isValid()) { + connection(); + } + return preparedQuery(sql, (conn, statement) -> conn.prepareStatement(sql), resultSetMapper, preparedParameters); + } + + /** + * Executes a prepared query on the JDBC connection and maps the result set using the provided ResultSetMapper. + * + * @param sql The SQL query to execute. + * @param preparedStatementFactory The factory to create the prepared statement. + * @param resultSetMapper The mapper to map the result set to an object. + * @param preparedParameters The prepared parameters for the query. + * @return The mapped object. + * @throws SQLException if a database access error occurs. + */ + public T preparedQuery(String sql, PreparedStatementFactory preparedStatementFactory, ResultSetMapper resultSetMapper, + PreparedParameter... preparedParameters) throws SQLException { + + Connection conn = connection(); + try (PreparedStatement preparedStatement = preparedStatementFactory.createPreparedStatement(conn, sql)) { + log.debug("Query sql '{}'", sql); + if (preparedParameters != null) { + for (int index = 0; index < preparedParameters.length; ++index) { + final PreparedParameter preparedParameter = preparedParameters[index]; + if (preparedParameter.getJdbcType() == null) { + preparedStatement.setObject(index + 1, preparedParameter.getValue()); + } else { + preparedStatement.setObject(index + 1, preparedParameter.getValue(), preparedParameter.getJdbcType().getVendorTypeNumber()); + } + } + } + try (ResultSet resultSet = preparedStatement.executeQuery()) { + if (resultSetMapper != null) { + return resultSetMapper.map(resultSet); + } + } + } + return null; + } + + public Statement createStatement(int fetchSize, int defaultFetchSize) throws SQLException { + final Statement statement = connection().createStatement(); + statement.setFetchSize(fetchSize <= 0 ? defaultFetchSize : fetchSize); + return statement; + } + + /** + * Functional interface for the initial operation on the JDBC connection. + */ + @FunctionalInterface + public interface InitialOperation { + + /** + * Applies the operation on the JDBC statement. + * + * @param statement The JDBC statement. + * @throws SQLException if a database access error occurs. + */ + void apply(Statement statement) throws SQLException; + } + + /** + * Functional interface for creating JDBC statements. + */ + @FunctionalInterface + public interface StatementFactory { + + /** + * Creates a JDBC statement. + * + * @param connection The JDBC connection. + * @return The JDBC statement. + * @throws SQLException if a database access error occurs. + */ + Statement createStatement(Connection connection) throws SQLException; + } + + /** + * Functional interface for creating JDBC prepared statements. + */ + @FunctionalInterface + public interface PreparedStatementFactory { + + /** + * Creates a JDBC prepared statement with the provided connection and SQL query. + * + * @param connection The JDBC connection. + * @param sql The SQL query. + * @return The JDBC prepared statement. + * @throws SQLException if a database access error occurs. + */ + PreparedStatement createPreparedStatement(Connection connection, String sql) throws SQLException; + } + + /** + * Functional interface for creating JDBC connections. + */ + @FunctionalInterface + @ThreadSafe + public interface ConnectionFactory { + + /** + * Creates a JDBC connection. + * + * @param config The JDBC configuration. + * @return The JDBC connection. + * @throws SQLException if a database access error occurs. + */ + Connection connect(JdbcConfig config) throws SQLException; + } + + /** + * Functional interface for mapping a ResultSet to an object of type T. + * + * @param The type of object to be mapped. + */ + @FunctionalInterface + public interface ResultSetMapper { + + /** + * Maps a ResultSet to an object of type T. + * + * @param rs The ResultSet to be mapped. + * @return The mapped object. + * @throws SQLException if a database access error occurs. + */ + T map(ResultSet rs) throws SQLException; + } + + /** + * Functional interface for consuming a ResultSet. + */ + @FunctionalInterface + public interface JdbcResultSetConsumer { + + /** + * Accepts a ResultSet and performs an operation on it. + * + * @param resultSet The ResultSet to be consumed. + * @throws SQLException if a database access error occurs. + */ + void accept(ResultSet resultSet) throws SQLException; + + } + + /** + * Creates a ConnectionFactory that uses a pattern-based URL with placeholder values. + * + * @param urlWithPlaceholder The URL pattern with placeholders. + * @param replaces The replacement values for the placeholders. + * @return The ConnectionFactory instance. + */ + @SuppressWarnings("unchecked") + public static ConnectionFactory createPatternConnectionFactory(String urlWithPlaceholder, String... replaces) { + return config -> { + String url; + if (replaces != null && replaces.length > 0) { + url = String.format(urlWithPlaceholder, (Object[]) replaces); + } else { + url = urlWithPlaceholder; + } + log.debug("URL: {}", url); + Connection connection = DriverManager.getConnection(url, config.asProperties()); + log.debug("User [{}] Connected to {}", config.getUser(), url); + return connection; + }; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/JdbcConnectionProvider.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/JdbcConnectionProvider.java new file mode 100644 index 0000000000..602208eb63 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/JdbcConnectionProvider.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.connector.jdbc.connection; + +import org.apache.eventmesh.connector.jdbc.exception.JdbcConnectionException; + +import java.sql.Connection; +import java.sql.SQLException; + +/** + * Obtaining a database connection and checking its validity. + */ +public interface JdbcConnectionProvider extends AutoCloseable { + + /** + * Obtains a database connection. + * + * @return A database connection. + */ + JC getConnection(); + + JC newConnection(); + + /** + * Checks if a database connection is valid. + * + * @param connection The database connection to check. + * @param timeout The timeout in seconds. + * @return True if the connection is valid, false otherwise. + * @throws JdbcConnectionException If there is an error checking the connection. + * @throws SQLException If there is an error with the SQL query. + */ + boolean isValid(Connection connection, int timeout) throws JdbcConnectionException, SQLException; + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/PreparedParameter.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/PreparedParameter.java new file mode 100644 index 0000000000..4461e1041b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/PreparedParameter.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.connector.jdbc.connection; + +import java.sql.JDBCType; + +import lombok.Data; + +/** + * Represents a parameter for a prepared statement. + */ +@Data +public class PreparedParameter { + + private Object value; + + private JDBCType jdbcType; + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/mysql/MysqlJdbcConnection.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/mysql/MysqlJdbcConnection.java new file mode 100644 index 0000000000..2a7514c09a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/connection/mysql/MysqlJdbcConnection.java @@ -0,0 +1,189 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.connection.mysql; + +import org.apache.eventmesh.connector.jdbc.config.JdbcConfig; +import org.apache.eventmesh.connector.jdbc.connection.JdbcConnection; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlDialectSql; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.utils.MysqlUtils; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.OptionalLong; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MysqlJdbcConnection extends JdbcConnection { + + private static final int DEFAULT_CONNECT_TIMEOUT_SECOND = 10; + + public static final String URL_WITH_PLACEHOLDER = "jdbc:mysql://%s:%s/?useInformationSchema=true" + + "&nullCatalogMeansCurrent=false&useUnicode=true&characterEncoding=UTF-8" + + "&characterSetResults=UTF-8&zeroDateTimeBehavior=CONVERT_TO_NULL&connectTimeout=%s"; + + public MysqlJdbcConnection(JdbcConfig jdbcConfig, InitialOperation initialOperation, ConnectionFactory connectionFactory) { + super(jdbcConfig, initialOperation, connectionFactory); + } + + public MysqlJdbcConnection(JdbcConfig jdbcConfig, InitialOperation initialOperation, ConnectionFactory connectionFactory, + boolean lazyConnection) { + super(jdbcConfig, initialOperation, connectionFactory, lazyConnection); + } + + public MysqlJdbcConnection(JdbcConfig jdbcConfig, InitialOperation initialOperation) { + super(jdbcConfig, initialOperation, getPatternConnectionFactory(jdbcConfig)); + } + + public MysqlJdbcConnection(JdbcConfig jdbcConfig, InitialOperation initialOperation, boolean lazyConnection) { + super(jdbcConfig, initialOperation, getPatternConnectionFactory(jdbcConfig), lazyConnection); + } + + private static ConnectionFactory getPatternConnectionFactory(JdbcConfig jdbcConfig) { + return JdbcConnection.createPatternConnectionFactory(URL_WITH_PLACEHOLDER, jdbcConfig.getHostname(), String.valueOf(jdbcConfig.getPort()), + String.valueOf(jdbcConfig.getConnectTimeout() <= 0 ? DEFAULT_CONNECT_TIMEOUT_SECOND : jdbcConfig.getConnectTimeout())); + } + + /** + * Checks if GTID (Global Transaction Identifier) is enabled on the database server. + * + * @return true if GTID is enabled, false otherwise. + */ + public boolean enableGTID() { + + boolean enableGTID = false; + try { + enableGTID = query(MysqlDialectSql.SHOW_GTID_STATUS.ofSQL(), new ResultSetMapper() { + + /** + * Maps a ResultSet to an object of type T. + * + * @param rs The ResultSet to be mapped. + * @return The mapped object. + * @throws SQLException if a database access error occurs. + */ + @Override + public Boolean map(ResultSet rs) throws SQLException { + while (rs.next()) { + if ("ON".equalsIgnoreCase(rs.getString(2))) { + return true; + } + } + return false; + } + }); + } catch (SQLException e) { + log.error("Get executed gtid error", e); + } + + return enableGTID; + } + + /** + * Retrieves the executed GTID from the Mysql database. + * + * @return The executed GTID as a String. + */ + public String executedGTID() { + + try { + return query(MysqlDialectSql.SHOW_MASTER_STATUS.ofSQL(), new ResultSetMapper() { + + /** + * Maps a ResultSet to an object of type T. + * + * @param rs The ResultSet to be mapped. + * @return The mapped object. + * @throws SQLException if a database access error occurs. + */ + @Override + public String map(ResultSet rs) throws SQLException { + if (rs.next() && rs.getMetaData().getColumnCount() > 4) { + return rs.getString(5); + } + // Return an empty string if no GTID is found. + return ""; + } + }); + } catch (SQLException e) { + log.error("Get executed gtid error", e); + } + return ""; + } + + /** + * Get the purged GTID values from MySQL (gtid_purged value) + * + * @return A GTID String; may be empty if not using GTIDs or none have been purged yet + */ + public String purgedGTID() { + + try { + + /** + * +----------------------------------------------+ + * | @@global.gtid_purged | + * +----------------------------------------------+ + * | e584735d-fde7-11ed-bf67-0242ac110002:1-12918 | + * +----------------------------------------------+ + */ + return query(MysqlDialectSql.SELECT_PURGED_GTID.ofSQL(), new ResultSetMapper() { + + /** + * Maps a ResultSet to an object of type T. + * + * @param rs The ResultSet to be mapped. + * @return The mapped object. + * @throws SQLException if a database access error occurs. + */ + @Override + public String map(ResultSet rs) throws SQLException { + if (rs.next() && rs.getMetaData().getColumnCount() > 4) { + return rs.getString(1); + } + // Return an empty string if no GTID is found. + return ""; + } + }); + } catch (SQLException e) { + log.error("Get executed gtid error", e); + } + return ""; + } + + public OptionalLong getRowCount4Table(TableId tableId) { + try { + // select database + execute(MysqlDialectSql.SELECT_DATABASE.ofWrapperSQL(MysqlUtils.wrapper(tableId.getCatalogName()))); + // The number of rows. Some storage engines, such as MyISAM, store the exact count. For other storage engines, + // such as InnoDB, this value is an approximation, and may vary from the actual value by as much as 40% to 50%. + // In such cases, use SELECT COUNT(*) to obtain an accurate count. + return query(MysqlDialectSql.SHOW_TABLE_STATUS.ofWrapperSQL(tableId.getTableName()), rs -> { + if (rs.next()) { + return OptionalLong.of(rs.getLong(5)); + } + return OptionalLong.empty(); + }); + } catch (SQLException e) { + log.error("Error get number of rows in table {} : {}", tableId, e.getMessage()); + } + return OptionalLong.empty(); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/context/mysql/MysqlOffsetContext.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/context/mysql/MysqlOffsetContext.java new file mode 100644 index 0000000000..4a19ae6b31 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/context/mysql/MysqlOffsetContext.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.connector.jdbc.context.mysql; + +import org.apache.eventmesh.connector.jdbc.UniversalOffsetContext; + +import java.util.Map; + +public class MysqlOffsetContext extends UniversalOffsetContext { + + private volatile boolean snapshotRunning = false; + + private volatile boolean snapshotCompleted = false; + + @Override + public Map getOffset() { + return null; + } + + @Override + public boolean isSnapshotRunning() { + return snapshotRunning; + } + + @Override + public void markSnapshotRunning() { + this.snapshotRunning = true; + } + + @Override + public void markSnapshotCompleted() { + this.snapshotCompleted = true; + } + + @Override + public boolean isSnapshotCompleted() { + return this.snapshotCompleted; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/context/mysql/MysqlPartition.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/context/mysql/MysqlPartition.java new file mode 100644 index 0000000000..bfba727775 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/context/mysql/MysqlPartition.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.connector.jdbc.context.mysql; + +import org.apache.eventmesh.connector.jdbc.AbstractPartition; +import org.apache.eventmesh.connector.jdbc.Partition; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import java.util.HashMap; +import java.util.Map; + +public class MysqlPartition extends AbstractPartition implements Partition { + + private static final String TABLE_ID = "tableId"; + + private Map partitions = new HashMap<>(); + + public MysqlPartition(TableId tableId) { + partitions.put(TABLE_ID, tableId.toString()); + } + + public MysqlPartition() { + + } + + @Override + public Map getPartition() { + return partitions; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/ddl/AbstractDdlParser.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/ddl/AbstractDdlParser.java new file mode 100644 index 0000000000..d61d8d9b1f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/ddl/AbstractDdlParser.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.connector.jdbc.ddl; + +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import lombok.Getter; + +public abstract class AbstractDdlParser implements DdlParser { + + // Indicates whether to skip parsing views. + private final boolean skipViews; + + // Indicates whether to skip parsing comments. + private final boolean skipComments; + + @Getter + private final TableId tableId; + + public AbstractDdlParser(boolean skipViews, boolean skipComments) { + this.skipViews = skipViews; + this.skipComments = skipComments; + this.tableId = new TableId(); + } + + @Override + public void setCurrentDatabase(String databaseName) { + this.tableId.setCatalogName(databaseName); + } + + @Override + public void setCurrentSchema(String schema) { + this.tableId.setSchemaName(schema); + } + + public String getCurrentDatabase() { + return this.tableId.getCatalogName(); + } + + public boolean isSkipViews() { + return skipViews; + } + + public boolean isSkipComments() { + return skipComments; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/ddl/DdlParser.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/ddl/DdlParser.java new file mode 100644 index 0000000000..0199fbcd92 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/ddl/DdlParser.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.connector.jdbc.ddl; + +/** + * Interface for parsing Data Definition Language (DDL) SQL statements. + */ +public interface DdlParser { + + /** + * Parses the given DDL SQL statement with a default callback. + * + * @param ddlSql The DDL SQL statement to parse. + */ + default void parse(String ddlSql) { + parse(ddlSql, null); + } + + /** + * Parses the given DDL SQL statement and provides a callback for handling the parsed events. + * + * @param ddlSql The DDL SQL statement to parse. + * @param callback The DdlParserCallback to handle the parsed events. + */ + void parse(String ddlSql, DdlParserCallback callback); + + /** + * Sets the current database name for the parser. + * + * @param databaseName The name of the current database. + */ + void setCurrentDatabase(String databaseName); + + /** + * Sets the current schema for the parser. + * + * @param schema The name of the current schema. + */ + void setCurrentSchema(String schema); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/ddl/DdlParserCallback.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/ddl/DdlParserCallback.java new file mode 100644 index 0000000000..392e4420a0 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/ddl/DdlParserCallback.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.jdbc.ddl; + +import org.apache.eventmesh.connector.jdbc.event.Event; + +/** + * A functional interface for handling events generated during DDL parsing. + */ +@FunctionalInterface +public interface DdlParserCallback { + + /** + * Handles the specified event. + * + * @param event The event generated during DDL parsing. + */ + void handle(Event event); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/AbstractEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/AbstractEvent.java new file mode 100644 index 0000000000..a5c7adf985 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/AbstractEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public abstract class AbstractEvent implements Event { + + private final TableId tableId; + + private JdbcConnectData data; + + public AbstractEvent(TableId tableId) { + this.tableId = tableId; + this.data = new JdbcConnectData(); + } + + public AbstractEvent(TableId tableId, JdbcConnectData data) { + this.tableId = tableId; + this.data = data; + } + + /** + * Gets the table ID of the event. + * + * @return The table ID. + */ + @Override + public TableId getTableId() { + return tableId; + } + + /** + * @return + */ + @Override + public JdbcConnectData getJdbcConnectData() { + return data; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/AlertDatabaseEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/AlertDatabaseEvent.java new file mode 100644 index 0000000000..f0d700cdc9 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/AlertDatabaseEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public class AlertDatabaseEvent extends GeneralSchemaChangeEvent { + + public AlertDatabaseEvent(TableId tableId) { + super(tableId); + } + + public AlertDatabaseEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } + + @Override + public SchemaChangeEventType getSchemaChangeEventType() { + return SchemaChangeEventType.DATABASE_ALERT; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/AlertTableEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/AlertTableEvent.java new file mode 100644 index 0000000000..dfb8250fa2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/AlertTableEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public class AlertTableEvent extends GeneralSchemaChangeEvent { + + public AlertTableEvent(TableId tableId) { + super(tableId); + } + + public AlertTableEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } + + @Override + public SchemaChangeEventType getSchemaChangeEventType() { + return SchemaChangeEventType.TABLE_ALERT; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/CreateDatabaseEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/CreateDatabaseEvent.java new file mode 100644 index 0000000000..ed00188a0d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/CreateDatabaseEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public class CreateDatabaseEvent extends GeneralSchemaChangeEvent { + + public CreateDatabaseEvent(TableId tableId) { + super(tableId); + } + + public CreateDatabaseEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } + + @Override + public SchemaChangeEventType getSchemaChangeEventType() { + return SchemaChangeEventType.DATABASE_CREATE; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/CreateTableEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/CreateTableEvent.java new file mode 100644 index 0000000000..76d1ff6968 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/CreateTableEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public class CreateTableEvent extends GeneralSchemaChangeEvent { + + public CreateTableEvent(TableId tableId) { + super(tableId); + } + + public CreateTableEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } + + @Override + public SchemaChangeEventType getSchemaChangeEventType() { + return SchemaChangeEventType.TABLE_CREATE; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DataChangeEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DataChangeEvent.java new file mode 100644 index 0000000000..2e22de34a8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DataChangeEvent.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.jdbc.event; + +/** + * Represents a data change event, extending the common event interface. + */ +public interface DataChangeEvent extends Event { + + /** + * Gets the type of data change event. + * + * @return The data change event type. + */ + DataChangeEventType getDataChangeEventType(); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DataChangeEventType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DataChangeEventType.java new file mode 100644 index 0000000000..be79cb3ebf --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DataChangeEventType.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.jdbc.event; + +public enum DataChangeEventType { + + INSERT("I"), UPDATE("U"), DELETE("D"); + private final String code; + + DataChangeEventType(String code) { + this.code = code; + } + + public String ofCode() { + return this.code; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DeleteDataEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DeleteDataEvent.java new file mode 100644 index 0000000000..987984bfce --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DeleteDataEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public class DeleteDataEvent extends GeneralDataChangeEvent { + + public DeleteDataEvent(TableId tableId) { + super(tableId); + } + + public DeleteDataEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } + + @Override + public DataChangeEventType getDataChangeEventType() { + return DataChangeEventType.DELETE; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DropDatabaseEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DropDatabaseEvent.java new file mode 100644 index 0000000000..0b5459514c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DropDatabaseEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public class DropDatabaseEvent extends GeneralSchemaChangeEvent { + + public DropDatabaseEvent(TableId tableId) { + super(tableId); + } + + public DropDatabaseEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } + + @Override + public SchemaChangeEventType getSchemaChangeEventType() { + return SchemaChangeEventType.DATABASE_DROP; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DropTableEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DropTableEvent.java new file mode 100644 index 0000000000..395bbf4686 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/DropTableEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public class DropTableEvent extends GeneralSchemaChangeEvent { + + public DropTableEvent(TableId tableId) { + super(tableId); + } + + public DropTableEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } + + @Override + public SchemaChangeEventType getSchemaChangeEventType() { + return SchemaChangeEventType.TABLE_DROP; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/Event.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/Event.java new file mode 100644 index 0000000000..7b254f960d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/Event.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +/** + * Top Event interface + */ +public interface Event { + + /** + * Gets the table ID of the event. + * + * @return The table ID. + */ + TableId getTableId(); + + JdbcConnectData getJdbcConnectData(); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/EventConsumer.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/EventConsumer.java new file mode 100644 index 0000000000..9ad6d453c4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/EventConsumer.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.jdbc.event; + +/** + * Functional interface for consuming events. + */ +@FunctionalInterface +public interface EventConsumer { + + /** + * Accepts a snapshot event. + * + * @param event the snapshot event to be consumed + */ + void accept(Event event); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/EventHandler.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/EventHandler.java new file mode 100644 index 0000000000..f37c5a9018 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/EventHandler.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.jdbc.event; + +/** + * Represents a handler for snapshot events. + */ +@FunctionalInterface +public interface EventHandler { + + /** + * Handles a snapshot event. + * + * @param event The SnapshotEvent to handle. + */ + void handle(Event event); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/GeneralDataChangeEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/GeneralDataChangeEvent.java new file mode 100644 index 0000000000..c6a9222376 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/GeneralDataChangeEvent.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.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public abstract class GeneralDataChangeEvent extends AbstractEvent implements DataChangeEvent { + + public GeneralDataChangeEvent(TableId tableId) { + super(tableId, new JdbcConnectData(JdbcConnectData.DATA_CHANGES)); + } + + public GeneralDataChangeEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/GeneralSchemaChangeEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/GeneralSchemaChangeEvent.java new file mode 100644 index 0000000000..80996203c5 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/GeneralSchemaChangeEvent.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.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public abstract class GeneralSchemaChangeEvent extends AbstractEvent implements SchemaChangeEvent { + + public GeneralSchemaChangeEvent(TableId tableId) { + super(tableId, new JdbcConnectData(JdbcConnectData.SCHEMA_CHANGES)); + } + + public GeneralSchemaChangeEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/InsertDataEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/InsertDataEvent.java new file mode 100644 index 0000000000..593f14574d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/InsertDataEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public class InsertDataEvent extends GeneralDataChangeEvent { + + public InsertDataEvent(TableId tableId) { + super(tableId); + } + + public InsertDataEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } + + @Override + public DataChangeEventType getDataChangeEventType() { + return DataChangeEventType.INSERT; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/SchemaChangeEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/SchemaChangeEvent.java new file mode 100644 index 0000000000..9cfe336072 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/SchemaChangeEvent.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.connector.jdbc.event; + +/** + * Represents a schema change event, extending the common event interface. + */ +public interface SchemaChangeEvent extends Event { + + /** + * Gets the type of schema change event. + * + * @return The schema change event type. + */ + SchemaChangeEventType getSchemaChangeEventType(); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/SchemaChangeEventType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/SchemaChangeEventType.java new file mode 100644 index 0000000000..fbf51ef2e8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/SchemaChangeEventType.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.connector.jdbc.event; + +public enum SchemaChangeEventType { + + DATABASE_CREATE("D", "C"), + DATABASE_DROP("D", "D"), + DATABASE_ALERT("D", "A"), + TABLE_CREATE("T", "C"), + TABLE_DROP("T", "D"), + TABLE_ALERT("T", "A"), + ; + private final String type; + private final String operationType; + + SchemaChangeEventType(String type, String operationType) { + this.type = type; + this.operationType = operationType; + } + + public String ofType() { + return this.type; + } + + public String ofOperationType() { + return this.operationType; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/UpdateDataEvent.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/UpdateDataEvent.java new file mode 100644 index 0000000000..1f38c3ff12 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/event/UpdateDataEvent.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.connector.jdbc.event; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +/** + * Represents an event that indicates an update in data. + */ +public class UpdateDataEvent extends GeneralDataChangeEvent { + + public UpdateDataEvent(TableId tableId) { + super(tableId); + } + + public UpdateDataEvent(TableId tableId, JdbcConnectData data) { + super(tableId, data); + } + + @Override + public DataChangeEventType getDataChangeEventType() { + return DataChangeEventType.UPDATE; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/CatalogException.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/CatalogException.java new file mode 100644 index 0000000000..17fa873fbf --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/CatalogException.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.connector.jdbc.exception; + +public class CatalogException extends RuntimeException { + + /** + * Constructs a new runtime exception with {@code null} as its detail message. The cause is not initialized, and may subsequently be initialized + * by a call to {@link #initCause}. + */ + public CatalogException() { + } + + /** + * Constructs a new runtime exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + public CatalogException(String message) { + super(message); + } + + /** + * Constructs a new runtime exception with the specified detail message and cause.

Note that the detail message associated with {@code cause} + * is + * not automatically incorporated in this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public CatalogException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of + * cause). This constructor is useful for runtime exceptions + * that are little more than wrappers for other throwables. + * + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public CatalogException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new runtime exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled + * or disabled. + * + * @param message the detail message. + * @param cause the cause. (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled or disabled + * @param writableStackTrace whether or not the stack trace should be writable + * @since 1.7 + */ + public CatalogException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/DataTypeConvertException.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/DataTypeConvertException.java new file mode 100644 index 0000000000..f0bbb02593 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/DataTypeConvertException.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.connector.jdbc.exception; + +public class DataTypeConvertException extends RuntimeException { + + /** + * Constructs a new runtime exception with {@code null} as its detail message. The cause is not initialized, and may subsequently be initialized + * by a call to {@link #initCause}. + */ + public DataTypeConvertException() { + } + + /** + * Constructs a new runtime exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + public DataTypeConvertException(String message) { + super(message); + } + + /** + * Constructs a new runtime exception with the specified detail message and cause.

Note that the detail message associated with {@code cause} + * is + * not automatically incorporated in this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public DataTypeConvertException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of + * cause). This constructor is useful for runtime exceptions + * that are little more than wrappers for other throwables. + * + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public DataTypeConvertException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new runtime exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled + * or disabled. + * + * @param message the detail message. + * @param cause the cause. (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled or disabled + * @param writableStackTrace whether or not the stack trace should be writable + * @since 1.7 + */ + public DataTypeConvertException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/DatabaseNotExistException.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/DatabaseNotExistException.java new file mode 100644 index 0000000000..5c363d28f4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/DatabaseNotExistException.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.connector.jdbc.exception; + +public class DatabaseNotExistException extends RuntimeException { + + /** + * Constructs a new runtime exception with {@code null} as its detail message. The cause is not initialized, and may subsequently be initialized + * by a call to {@link #initCause}. + */ + public DatabaseNotExistException() { + } + + /** + * Constructs a new runtime exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + public DatabaseNotExistException(String message) { + super(message); + } + + /** + * Constructs a new runtime exception with the specified detail message and cause.

Note that the detail message associated with {@code cause} + * is + * not automatically incorporated in this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public DatabaseNotExistException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of + * cause). This constructor is useful for runtime exceptions + * that are little more than wrappers for other throwables. + * + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public DatabaseNotExistException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new runtime exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled + * or disabled. + * + * @param message the detail message. + * @param cause the cause. (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled or disabled + * @param writableStackTrace whether or not the stack trace should be writable + * @since 1.7 + */ + public DatabaseNotExistException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/JdbcConnectionException.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/JdbcConnectionException.java new file mode 100644 index 0000000000..dde57fc349 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/JdbcConnectionException.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.connector.jdbc.exception; + +public class JdbcConnectionException extends RuntimeException { + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/TableNotExistException.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/TableNotExistException.java new file mode 100644 index 0000000000..dc5a58dc03 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/exception/TableNotExistException.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.connector.jdbc.exception; + +public class TableNotExistException extends RuntimeException { + + /** + * Constructs a new runtime exception with {@code null} as its detail message. The cause is not initialized, and may subsequently be initialized + * by a call to {@link #initCause}. + */ + public TableNotExistException() { + } + + /** + * Constructs a new runtime exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + public TableNotExistException(String message) { + super(message); + } + + /** + * Constructs a new runtime exception with the specified detail message and cause.

Note that the detail message associated with {@code cause} + * is not automatically incorporated in this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public TableNotExistException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of + * cause). This constructor is useful for runtime exceptions + * that are little more than wrappers for other throwables. + * + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public TableNotExistException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new runtime exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled + * or disabled. + * + * @param message the detail message. + * @param cause the cause. (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled or disabled + * @param writableStackTrace whether or not the stack trace should be writable + * @since 1.7 + */ + public TableNotExistException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/server/JdbcConnectorServer.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/server/JdbcConnectorServer.java new file mode 100644 index 0000000000..0309aa3442 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/server/JdbcConnectorServer.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.connector.jdbc.server; + +import org.apache.eventmesh.connector.jdbc.config.JdbcServerConfig; +import org.apache.eventmesh.connector.jdbc.source.JdbcSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +/** + * JDBC connector server + */ +public class JdbcConnectorServer { + + public static void main(String[] args) throws Exception { + JdbcServerConfig serverConfig = ConfigUtil.parse(JdbcServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application jdbcSourceApp = new Application(); + jdbcSourceApp.run(JdbcSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + // TODO support + } + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractEngine.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractEngine.java new file mode 100644 index 0000000000..2d1080e05b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractEngine.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.connector.jdbc.source; + +import org.apache.eventmesh.common.ThreadWrapper; +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import org.apache.commons.collections4.CollectionUtils; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractEngine extends ThreadWrapper implements Engine { + + private final Set includeDatabaseTable = new HashSet<>(64); + + protected final JdbcSourceConfig jdbcSourceConfig; + + protected final SourceConnectorConfig sourceConnectorConfig; + + protected final DbDialect databaseDialect; + + public AbstractEngine(JdbcSourceConfig jdbcSourceConfig, DbDialect databaseDialect) { + this.jdbcSourceConfig = jdbcSourceConfig; + this.sourceConnectorConfig = this.jdbcSourceConfig.getSourceConnectorConfig(); + this.databaseDialect = databaseDialect; + + calculateNeedHandleTable(); + } + + @Override + public Set getHandledTables() { + return includeDatabaseTable; + } + + protected Set calculateNeedHandleTable() { + // Get the database and table include and exclude lists from the connector configuration + List databaseIncludeList = sourceConnectorConfig.getDatabaseIncludeList(); + + // If the database include list is empty, get a list of all databases and use that as the include list + if (CollectionUtils.isEmpty(databaseIncludeList)) { + List allDatabases = databaseDialect.listDatabases(); + databaseIncludeList = new ArrayList<>(allDatabases); + } + Set defaultExcludeDatabase = defaultExcludeDatabase(); + if (CollectionUtils.isNotEmpty(defaultExcludeDatabase)) { + databaseIncludeList.removeAll(defaultExcludeDatabase); + } + + List databaseExcludeList = sourceConnectorConfig.getDatabaseExcludeList(); + // Remove the default excluded databases from the include list + if (CollectionUtils.isNotEmpty(databaseExcludeList)) { + databaseIncludeList.removeAll(databaseExcludeList); + } + + List tableIncludeList = sourceConnectorConfig.getTableIncludeList(); + // Create a list of included tables based on the table include list + List includeTableList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(tableIncludeList)) { + List tableIdList = buildTableId(tableIncludeList); + includeTableList.addAll(tableIdList); + } + + // If the table include list is empty, get a list of all tables for each database in the include list + if (CollectionUtils.isEmpty(tableIncludeList)) { + for (String database : databaseIncludeList) { + try { + List tableIds = databaseDialect.listTables(database); + includeTableList.addAll(tableIds); + } catch (SQLException e) { + log.warn("List database[{}] table error", database, e); + } + } + } + + List tableExcludeList = sourceConnectorConfig.getTableExcludeList(); + // Remove any tables in the exclude list from the included tables list + if (CollectionUtils.isNotEmpty(tableExcludeList)) { + includeTableList.removeAll(buildTableId(tableExcludeList)); + } + + includeDatabaseTable.addAll(includeTableList); + + return includeDatabaseTable; + } + + private List buildTableId(List tables) { + return Optional.ofNullable(tables).orElse(new ArrayList<>(0)).stream().map(table -> { + String[] split = table.split("\\."); + return new TableId(split[0], null, split[1]); + }).collect(Collectors.toList()); + } + + protected abstract Set defaultExcludeDatabase(); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractEventMeshJdbcEventTask.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractEventMeshJdbcEventTask.java new file mode 100644 index 0000000000..3f7301fa7a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractEventMeshJdbcEventTask.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.connector.jdbc.source; + +import org.apache.eventmesh.common.ThreadWrapper; +import org.apache.eventmesh.connector.jdbc.event.Event; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public abstract class AbstractEventMeshJdbcEventTask extends ThreadWrapper implements EventMeshJdbcEventTask { + + protected BlockingQueue eventBlockingQueue = new LinkedBlockingQueue<>(10000); + + @Override + public void shutdown() { + super.shutdown(); + } + + @Override + public void close() throws Exception { + shutdown(); + } + + @Override + public void put(Event event) throws InterruptedException { + eventBlockingQueue.put(event); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractEventMeshJdbcTask.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractEventMeshJdbcTask.java new file mode 100644 index 0000000000..536ef5d18e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractEventMeshJdbcTask.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.connector.jdbc.source; + +import org.apache.eventmesh.common.ThreadWrapper; + +public abstract class AbstractEventMeshJdbcTask extends ThreadWrapper implements EventMeshJdbcTask { + + @Override + public void shutdown() { + super.shutdown(); + } + + @Override + public void close() throws Exception { + shutdown(); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractJdbcTaskManager.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractJdbcTaskManager.java new file mode 100644 index 0000000000..b398ffa17b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/AbstractJdbcTaskManager.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.connector.jdbc.source; + +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public abstract class AbstractJdbcTaskManager implements JdbcTaskManager { + + protected Map tableIdJdbcTaskMap = new ConcurrentHashMap<>(); + + protected Set includeDatabaseTable; + + protected JdbcSourceConfig jdbcSourceConfig; + + protected List taskList = new ArrayList<>(128); + + protected List listeners = new ArrayList<>(16); + + @Override + public void start() { + taskList.forEach(EventMeshJdbcTask::start); + } + + @Override + public void shutdown() { + taskList.forEach(EventMeshJdbcTask::shutdown); + } + + @Override + public void close() throws Exception { + shutdown(); + } + + @Override + public void registerListener(TaskManagerListener listener) { + if (!Objects.isNull(listener)) { + listeners.add(listener); + } + } + + public abstract Task select(TableId tableId); +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/Engine.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/Engine.java new file mode 100644 index 0000000000..fa2cc73b4a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/Engine.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.connector.jdbc.source; + +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import java.util.Set; + +/** + * Engine interface represents the core engine + */ +public interface Engine { + + /** + * Initializes the engine. + */ + void init(); + + /** + * Starts the engine. + */ + void start(); + + /** + * Retrieves the set of TableId objects representing the tables that the engine handles. + * + * @return The set of handled TableId objects. + */ + Set getHandledTables(); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/EventDispatcher.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/EventDispatcher.java new file mode 100644 index 0000000000..17e59335eb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/EventDispatcher.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.connector.jdbc.source; + +import org.apache.eventmesh.connector.jdbc.event.Event; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EventDispatcher { + + private SourceJdbcTaskManager sourceJdbcTaskManager; + + public EventDispatcher(SourceJdbcTaskManager sourceJdbcTaskManager) { + this.sourceJdbcTaskManager = sourceJdbcTaskManager; + } + + /** + * Dispatch CDC events. + * + * @param event The CDC event to be dispatched. + */ + public void dispatch(Event event) { + TableId tableId = event.getTableId(); + SourceEventMeshJdbcEventTask task = sourceJdbcTaskManager.select(tableId); + try { + // Put the CDC event into the selected JDBC task. + task.put(event); + } catch (InterruptedException e) { + log.warn("Dispatch CdcEvent error", e); + } + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/EventMeshJdbcEventTask.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/EventMeshJdbcEventTask.java new file mode 100644 index 0000000000..95294f3eae --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/EventMeshJdbcEventTask.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.connector.jdbc.source; + +import org.apache.eventmesh.connector.jdbc.event.Event; +import org.apache.eventmesh.connector.jdbc.event.EventHandler; + +/** + * The EventMeshJdbcTask interface represents a task that interacts with the EventMesh through a JDBC connection. It extends the AutoCloseable + * interface, allowing the task to be managed efficiently. + */ +public interface EventMeshJdbcEventTask extends EventMeshJdbcTask { + + /** + * Puts an event into the task for processing. + * + * @param event The event to be processed. + * @throws InterruptedException If the operation is interrupted while waiting to put the event. + */ + void put(E event) throws InterruptedException; + + /** + * Registers a snapshot event handler to be executed when snapshot events occur. + * + * @param handler The SnapshotEventHandler to be registered. + */ + void registerEventHandler(EventHandler handler); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/EventMeshJdbcTask.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/EventMeshJdbcTask.java new file mode 100644 index 0000000000..c54d9e4d2f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/EventMeshJdbcTask.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.connector.jdbc.source; + +/** + * The EventMeshJdbcTask interface represents a task that interacts with the EventMesh through a JDBC connection. It extends the AutoCloseable + * interface, allowing the task to be managed efficiently. + */ +public interface EventMeshJdbcTask extends AutoCloseable { + + /** + * Starts the EventMesh JDBC task, initializing any necessary resources or connections. + */ + void start(); + + /** + * Shuts down the EventMesh JDBC task, releasing any acquired resources or connections. + */ + void shutdown(); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/JdbcAllFactoryLoader.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/JdbcAllFactoryLoader.java new file mode 100644 index 0000000000..f3c09adb53 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/JdbcAllFactoryLoader.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.jdbc.source; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.apache.eventmesh.connector.jdbc.source.dialect.DatabaseDialectFactory; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.CdcEngineFactory; +import org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotEngineFactory; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import java.util.Objects; + +import lombok.experimental.UtilityClass; + +/** + * Get a CdcEngineFactory for a given database name + */ +@UtilityClass +public class JdbcAllFactoryLoader { + + /** + * Returns a CdcEngineFactory for the given database name. + *

Throws NullPointerException if databaseName is null.

+ *

Throws IllegalArgumentException if CdcEngineFactory is not supported for the given database name.

+ * + * @param databaseName Name of the database for which CdcEngineFactory is required. + * @return CdcEngineFactory for the given database name. + */ + public static CdcEngineFactory getCdcEngineFactory(String databaseName) { + checkNotNull(databaseName, "database name can not be null"); + CdcEngineFactory engineFactory = EventMeshExtensionFactory.getExtension(CdcEngineFactory.class, databaseName); + return checkNotNull(engineFactory, "CdcEngineFactory: " + databaseName + " is not supported"); + } + + /** + * Returns a DatabaseDialectFactory based on the specified database name. + * + * @param databaseName the name of the database + * @return the DatabaseDialectFactory for the specified database name + * @throws NullPointerException if the database name is null + * @throws IllegalArgumentException if the specified database name is not supported + */ + public static DatabaseDialectFactory getDatabaseDialectFactory(String databaseName) { + Objects.requireNonNull(databaseName, "database name can not be null"); + DatabaseDialectFactory databaseDialectFactory = EventMeshExtensionFactory.getExtension(DatabaseDialectFactory.class, databaseName); + Objects.requireNonNull(databaseDialectFactory, "DatabaseDialectFactory: " + databaseName + " is not supported"); + return databaseDialectFactory; + } + + public static SnapshotEngineFactory getSnapshotEngineFactory(String databaseName) { + Objects.requireNonNull(databaseName, "database name can not be null"); + SnapshotEngineFactory databaseDialectFactory = EventMeshExtensionFactory.getExtension(SnapshotEngineFactory.class, databaseName); + Objects.requireNonNull(databaseDialectFactory, "SnapshotEngineFactory: " + databaseName + " is not supported"); + return databaseDialectFactory; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/JdbcSourceConnector.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/JdbcSourceConnector.java new file mode 100644 index 0000000000..202d7b9ca4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/JdbcSourceConnector.java @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.jdbc.source; + +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.connector.jdbc.event.Event; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.DatabaseDialectFactory; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.CdcEngine; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.CdcEngineFactory; +import org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotEngine; +import org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotEngineFactory; +import org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotResult; +import org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotResult.SnapshotResultStatus; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.config.SourceConfig; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnector; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.commons.collections4.CollectionUtils; + +import java.util.List; +import java.util.Set; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class JdbcSourceConnector extends SourceConnector { + + private DatabaseDialect databaseDialect; + + private CdcEngine cdcEngine; + + private JdbcSourceConfig sourceConfig; + + private EventDispatcher dispatcher; + + private SourceJdbcTaskManager sourceJdbcTaskManager; + + private SnapshotEngine snapshotEngine; + + private TaskManagerCoordinator taskManagerCoordinator; + + public JdbcSourceConnector() { + this(null); + } + + protected JdbcSourceConnector(SourceConfig sourceConfig) { + super(sourceConfig); + } + + /** + * Returns the class type of the configuration for this Connector. + * + * @return Class type of the configuration + */ + @Override + public Class configClass() { + return JdbcSourceConfig.class; + } + + /** + * Initializes the Connector with the provided configuration. + * + * @param config Configuration object + * @throws Exception if initialization fails + */ + @Override + public void init(Config config) throws Exception { + + if (!(config instanceof JdbcSourceConfig)) { + throw new IllegalArgumentException("Config not be JdbcSourceConfig"); + } + this.sourceConfig = (JdbcSourceConfig) config; + doInit(); + } + + /** + * Initializes the Connector with the provided context. + * + * @param connectorContext connectorContext + * @throws Exception if initialization fails + */ + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (JdbcSourceConfig) sourceConnectorContext.getSourceConfig(); + doInit(); + } + + private void doInit() { + String databaseType = this.sourceConfig.getSourceConnectorConfig().getDatabaseType(); + + // Get the database dialect factory and create the database dialect. + final DatabaseDialectFactory databaseDialectFactory = JdbcAllFactoryLoader.getDatabaseDialectFactory(databaseType); + this.databaseDialect = databaseDialectFactory.createDatabaseDialect(sourceConfig); + this.databaseDialect.init(); + + // Get the snapshot engine factory and create the snapshot engine + final SnapshotEngineFactory snapshotEngineFactory = JdbcAllFactoryLoader.getSnapshotEngineFactory(databaseType); + this.snapshotEngine = snapshotEngineFactory.createSnapshotEngine(this.sourceConfig, this.databaseDialect); + this.snapshotEngine.registerSnapshotEventConsumer(this::eventConsumer); + this.snapshotEngine.init(); + + // Get the CDC engine factory and create the CDC engine. + final CdcEngineFactory cdcEngineFactory = JdbcAllFactoryLoader.getCdcEngineFactory(databaseType); + // Check if the CDC engine factory supports the JDBC protocol. + if (!cdcEngineFactory.acceptJdbcProtocol(this.databaseDialect.jdbcProtocol())) { + throw new IllegalArgumentException("CdcEngineFactory not supports " + databaseType); + } + // Set the CDC engine and register the CDC event consumer. + this.cdcEngine = cdcEngineFactory.createCdcEngine(this.sourceConfig, this.databaseDialect); + if (CollectionUtils.isEmpty(this.cdcEngine.getHandledTables())) { + throw new RuntimeException("No database tables need to be processed"); + } + this.cdcEngine.registerCdcEventConsumer(this::eventConsumer); + this.cdcEngine.init(); + + Set handledTables = this.snapshotEngine.getHandledTables(); + + // Create the task manager and dispatcher. + this.sourceJdbcTaskManager = new SourceJdbcTaskManager(handledTables, this.sourceConfig); + this.sourceJdbcTaskManager.init(); + + this.dispatcher = new EventDispatcher(this.sourceJdbcTaskManager); + + this.taskManagerCoordinator = new TaskManagerCoordinator(); + this.taskManagerCoordinator.registerTaskManager(SourceJdbcTaskManager.class.getName(), sourceJdbcTaskManager); + this.taskManagerCoordinator.init(); + } + + private void eventConsumer(Event event) { + this.dispatcher.dispatch(event); + } + + /** + * Starts the Connector. + * + * @throws Exception if the start operation fails + */ + @Override + @SuppressWarnings("unchecked") + public void start() throws Exception { + this.databaseDialect.start(); + this.taskManagerCoordinator.start(); + this.snapshotEngine.start(); + SnapshotResult result = this.snapshotEngine.execute(); + this.snapshotEngine.close(); + // success and skip status can run cdc engine + if (result.getStatus() != SnapshotResultStatus.ABORTED) { + log.info("Start Cdc Engine to handle cdc event"); + this.cdcEngine.setContext(result.getContext()); + this.cdcEngine.start(); + } + } + + /** + * Commits the specified ConnectRecord object. + * + * @param record ConnectRecord object to commit + */ + @Override + public void commit(ConnectRecord record) { + + } + + /** + * Returns the name of the Connector. + * + * @return String name of the Connector + */ + @Override + public String name() { + return "JDBC Source Connector"; + } + + /** + * Stops the Connector. + * + * @throws Exception if stopping fails + */ + @Override + public void stop() throws Exception { + + } + + @Override + public List poll() { + + List connectRecords = this.taskManagerCoordinator.poll(); + + return connectRecords; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/JdbcTaskManager.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/JdbcTaskManager.java new file mode 100644 index 0000000000..a7d3c5000e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/JdbcTaskManager.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.connector.jdbc.source; + +/** + * The JdbcTaskManager interface represents a manager for JDBC tasks. It extends the AutoCloseable interface, allowing the manager to be managed + * efficiently. + */ +public interface JdbcTaskManager extends AutoCloseable { + + /** + * Initializes the JDBC task manager, setting up any required configurations or resources. + */ + void init(); + + /** + * Starts the JDBC task manager, allowing it to begin managing tasks. + */ + void start(); + + /** + * Shuts down the JDBC task manager, releasing any acquired resources or stopping task management. + */ + void shutdown(); + + /** + * Registers a listener to receive events and notifications from the JDBC task manager. + * + * @param listener The listener to be registered. + */ + void registerListener(TaskManagerListener listener); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/SourceEventMeshJdbcEventTask.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/SourceEventMeshJdbcEventTask.java new file mode 100644 index 0000000000..0daa641cc6 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/SourceEventMeshJdbcEventTask.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.connector.jdbc.source; + +import org.apache.eventmesh.connector.jdbc.event.Event; +import org.apache.eventmesh.connector.jdbc.event.EventHandler; + +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +public class SourceEventMeshJdbcEventTask extends AbstractEventMeshJdbcEventTask { + + private final String taskName; + + private EventHandler eventHandler; + + public SourceEventMeshJdbcEventTask(String taskName) { + this.taskName = taskName; + + } + + @Override + public String getThreadName() { + return taskName; + } + + /** + * When an object implementing interface Runnable is used to create a thread, starting the thread causes the object's + * run method to be called in that separately executing + * thread. + *

+ * The general contract of the method run is that it may take any action whatsoever. + * + * @see Thread#run() + */ + @Override + public void run() { + while (isRunning) { + try { + Event event = eventBlockingQueue.poll(5, TimeUnit.SECONDS); + if (Objects.isNull(event)) { + continue; + } + eventHandler.handle(event); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + + /** + * Registers a snapshot event handler to be executed when snapshot events occur. + * + * @param handler The SnapshotEventHandler to be registered. + */ + @Override + public void registerEventHandler(EventHandler handler) { + this.eventHandler = handler; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/SourceJdbcTaskManager.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/SourceJdbcTaskManager.java new file mode 100644 index 0000000000..49e9c53a15 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/SourceJdbcTaskManager.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.connector.jdbc.source; + +import org.apache.eventmesh.connector.jdbc.JdbcConnectData; +import org.apache.eventmesh.connector.jdbc.event.Event; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.RandomTaskSelectStrategy; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.TaskSelectStrategy; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SourceJdbcTaskManager extends AbstractJdbcTaskManager { + + private final Set includeDatabaseTable; + + private final JdbcSourceConfig jdbcSourceConfig; + + private TaskSelectStrategy cdcTaskSelectStrategy; + + public SourceJdbcTaskManager(Set includeDatabaseTable, JdbcSourceConfig jdbcSourceConfig) { + this.jdbcSourceConfig = jdbcSourceConfig; + this.includeDatabaseTable = includeDatabaseTable == null ? new HashSet<>() : includeDatabaseTable; + } + + @SuppressWarnings("unchecked") + public void init() { + // init Jdbc Task + int maxTaskNum = this.jdbcSourceConfig.getSourceConnectorConfig().getMaxTask(); + int taskNum = Math.min(maxTaskNum, this.includeDatabaseTable.size()); + log.info("Source jdbc task num {}", taskNum); + for (int index = 0; index < taskNum; ++index) { + SourceEventMeshJdbcEventTask eventTask = new SourceEventMeshJdbcEventTask("source-jdbc-task-" + (index + 1)); + eventTask.registerEventHandler(this::doHandleEvent); + taskList.add(eventTask); + } + cdcTaskSelectStrategy = new RandomTaskSelectStrategy(taskList); + + } + + private void doHandleEvent(Event event) { + if (null == event) { + return; + } + JdbcConnectData jdbcConnectData = event.getJdbcConnectData(); + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord record = new ConnectRecord(partition, offset, System.currentTimeMillis(), jdbcConnectData); + List records = Collections.singletonList(record); + for (TaskManagerListener listener : listeners) { + listener.listen(records); + } + } + + @Override + public SourceEventMeshJdbcEventTask select(TableId tableId) { + return tableIdJdbcTaskMap.computeIfAbsent(tableId, key -> cdcTaskSelectStrategy.select(tableId)); + } + + public int getTaskCount() { + return tableIdJdbcTaskMap.size(); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/SourceMateData.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/SourceMateData.java new file mode 100644 index 0000000000..e1f6f28fd7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/SourceMateData.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.connector.jdbc.source; + +import lombok.Data; + +/** + * Represents metadata related to a data source. + */ +@Data +public class SourceMateData { + + /** + * The connector used for the connector source. e.g: mysql, oracle etc. + */ + private String connector; + + /** + * The name of the connector source. + */ + private String name; + + /** + * The timestamp when the metadata was captured. + */ + private long timestamp; + + /** + * Flag indicating whether this metadata belongs to a snapshot. + */ + private boolean snapshot; + + /** + * The catalog name associated with the connector source. + */ + private String catalogName; + + /** + * The schema name associated with the connector source. + */ + private String schemaName; + + /** + * The table name associated with the connector source. + */ + private String tableName; + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/TaskManagerCoordinator.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/TaskManagerCoordinator.java new file mode 100644 index 0000000000..a1572787d7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/TaskManagerCoordinator.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.connector.jdbc.source; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.commons.collections4.CollectionUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import lombok.extern.slf4j.Slf4j; + +/** + * The TaskManagerCoordinator is responsible for coordinating multiple JDBC task managers and managing the processing of ConnectRecords. It provides + * methods for registering task managers, initializing them, and starting their processing. + */ +@Slf4j +public class TaskManagerCoordinator { + + private static final int BATCH_MAX = 10; + private static final int DEFAULT_QUEUE_SIZE = 1 << 13; + + private BlockingQueue recordBlockingQueue = new LinkedBlockingQueue<>(DEFAULT_QUEUE_SIZE); + private Map taskManagerCache = new HashMap<>(8); + + /** + * Constructs a new TaskManagerCoordinator. + */ + public TaskManagerCoordinator() { + } + + /** + * Registers a JDBC task manager with the given name. + * + * @param name The name of the task manager. + * @param taskManager The JDBC task manager to register. + */ + public void registerTaskManager(String name, JdbcTaskManager taskManager) { + taskManagerCache.put(name, taskManager); + } + + /** + * Initializes all registered JDBC task managers. + */ + public void init() { + taskManagerCache.values().forEach(JdbcTaskManager::init); + + // Register a listener on each task manager to process incoming records and add them to the blocking queue. + taskManagerCache.values().forEach(taskManager -> taskManager.registerListener(records -> { + if (CollectionUtils.isEmpty(records)) { + return; + } + records.forEach(record -> { + try { + recordBlockingQueue.put(record); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + })); + } + + /** + * Starts the processing of all registered JDBC task managers. + */ + public void start() { + taskManagerCache.values().forEach(JdbcTaskManager::start); + } + + /** + * Polls for a batch of ConnectRecords from the blocking queue. + * + * @return A list of ConnectRecords, up to the maximum batch size defined by BATCH_MAX. + */ + public List poll() { + List records = new ArrayList<>(BATCH_MAX); + for (int index = 0; index < BATCH_MAX; ++index) { + try { + ConnectRecord record = recordBlockingQueue.poll(3, TimeUnit.SECONDS); + if (Objects.isNull(record)) { + break; + } + records.add(record); + } catch (InterruptedException e) { + break; + } + } + return records; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/TaskManagerListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/TaskManagerListener.java new file mode 100644 index 0000000000..abfbfcc5d6 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/TaskManagerListener.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.connector.jdbc.source; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.util.List; + +/** + * The TaskManagerListener is a functional interface used to listen for events from the TaskManager. It defines a single method, "listen", that takes + * a list of ConnectRecord objects as its parameter. + */ +@FunctionalInterface +public interface TaskManagerListener { + + /** + * Listens for events from the TaskManager and processes the given list of ConnectRecords. + * + * @param records The list of ConnectRecord objects to be processed. + */ + void listen(List records); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/config/JdbcSourceConfig.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/config/JdbcSourceConfig.java new file mode 100644 index 0000000000..b330c331bf --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/config/JdbcSourceConfig.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.jdbc.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class JdbcSourceConfig extends SourceConfig { + + private SourceConnectorConfig sourceConnectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/config/MysqlConfig.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/config/MysqlConfig.java new file mode 100644 index 0000000000..032921350f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/config/MysqlConfig.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.connector.jdbc.source.config; + +import lombok.Data; + +@Data +public class MysqlConfig { + + private int serverId; + + private boolean keepAlive = true; + + private long keepAliveInterval; + + private SnapshotLockingMode snapshotLockingMode = SnapshotLockingMode.MINIMAL; + + private boolean useGlobalLock = true; + + public enum SnapshotLockingMode { + + EXTENDED("extended"), + + MINIMAL("minimal"), + + NONE("none"); + + private final String value; + + SnapshotLockingMode(String value) { + this.value = value; + } + + public boolean usesLocking() { + return !value.equals(NONE.value); + } + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..a27dbfedb4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/config/SourceConnectorConfig.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.jdbc.source.config; + +import org.apache.eventmesh.connector.jdbc.config.JdbcConfig; + +import java.util.List; + +import lombok.Data; + +/** + * Represents the configuration for a database connector. + */ +@Data +public class SourceConnectorConfig { + + private static final int DEFAULT_SNAPSHOT_FETCH_SIZE = 100; + + /** + * Max task number,The maximum cannot exceed the number of tables scanned. If it exceeds, it will be set to the number of tables. + */ + private int maxTask; + + private int batchMaxRows; + + private boolean skipSnapshot = false; + + // A list of database names to include in the connector. + private List databaseIncludeList; + + // A list of database names to exclude from the connector. + private List databaseExcludeList; + + // A list of table names to include in the connector. + private List tableIncludeList; + + // A list of table names to exclude from the connector. + private List tableExcludeList; + + // database type e.g. mysql + private String databaseType; + + private int snapshotMaxThreads; + + // The snapshot mode also require handling the database schema (database and table schema) + private boolean snapshotSchema = true; + + // The snapshot mode require handling table data + private boolean snapshotData = true; + + private int snapshotFetchSize = DEFAULT_SNAPSHOT_FETCH_SIZE; + + private JdbcConfig jdbcConfig; + + private boolean skipViews = false; + + private boolean skipComments = false; + + // The configuration for the MySQL database. + private MysqlConfig mysqlConfig; + + private String name = "mysql-connector"; +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/AbstractGeneralDatabaseDialect.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/AbstractGeneralDatabaseDialect.java new file mode 100644 index 0000000000..ae497fce5c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/AbstractGeneralDatabaseDialect.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.connector.jdbc.source.dialect; + +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.connector.jdbc.connection.JdbcConnection; +import org.apache.eventmesh.connector.jdbc.exception.JdbcConnectionException; +import org.apache.eventmesh.connector.jdbc.source.config.SourceConnectorConfig; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public abstract class AbstractGeneralDatabaseDialect implements DatabaseDialect { + + private static final int DEFAULT_BATCH_MAX_ROWS = 20; + + private SourceConnectorConfig config; + + private int batchMaxRows = DEFAULT_BATCH_MAX_ROWS; + + public AbstractGeneralDatabaseDialect(SourceConnectorConfig config) { + this.config = config; + } + + @Override + public boolean isValid(Connection connection, int timeout) throws JdbcConnectionException, SQLException { + return connection == null ? false : connection.isValid(timeout); + } + + @Override + public PreparedStatement createPreparedStatement(Connection connection, String sql) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement(sql); + if (batchMaxRows > 0) { + preparedStatement.setFetchSize(batchMaxRows); + } + return preparedStatement; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/DatabaseDialectFactory.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/DatabaseDialectFactory.java new file mode 100644 index 0000000000..8f73f9f53e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/DatabaseDialectFactory.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.jdbc.source.dialect; + +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.openconnect.api.config.SourceConfig; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +/** + * Interface for creating a database dialect based on the provided source configuration. + */ +@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.JDBC_DATABASE_DIALECT) +public interface DatabaseDialectFactory { + + /** + * Creates a database dialect based on the provided source configuration. + * + * @param config the source configuration to create a database dialect for + * @return the created database dialect + */ + DatabaseDialect createDatabaseDialect(SourceConfig config); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/DatabaseType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/DatabaseType.java new file mode 100644 index 0000000000..2e56932004 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/DatabaseType.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.connector.jdbc.source.dialect; + +import org.apache.commons.lang3.StringUtils; + +public enum DatabaseType { + + MYSQL("mysql"); + + private String name; + + DatabaseType(String name) { + this.name = name; + } + + public static DatabaseType ofValue(String name) { + DatabaseType[] databaseTypes = values(); + for (DatabaseType databaseType : databaseTypes) { + if (StringUtils.equalsIgnoreCase(databaseType.name, name)) { + return databaseType; + } + } + return null; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/MysqlAntlr4DdlParser.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/MysqlAntlr4DdlParser.java new file mode 100644 index 0000000000..1cf69bde2f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/MysqlAntlr4DdlParser.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.connector.jdbc.source.dialect.antlr4.mysql; + +import org.apache.eventmesh.connector.jdbc.antlr4.Antlr4DdlParser; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlLexer; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser; +import org.apache.eventmesh.connector.jdbc.antlr4.listener.Antlr4DdlParserListener; +import org.apache.eventmesh.connector.jdbc.ddl.DdlParserCallback; +import org.apache.eventmesh.connector.jdbc.event.Event; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.listener.MySqlAntlr4DdlParserListener; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashSet; +import java.util.Set; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTree; + +public class MysqlAntlr4DdlParser extends Antlr4DdlParser { + + private DdlParserCallback callback; + + private final Set includeDatabaseTable; + + private final JdbcSourceConfig sourceConfig; + + public MysqlAntlr4DdlParser(boolean skipViews, boolean skipComments, Set includeDatabaseTable, JdbcSourceConfig sourceConfig) { + super(skipViews, skipComments); + this.includeDatabaseTable = includeDatabaseTable; + this.sourceConfig = sourceConfig; + } + + public MysqlAntlr4DdlParser(boolean skipViews, boolean skipComments, JdbcSourceConfig sourceConfig) { + this(skipViews, skipComments, new HashSet<>(), sourceConfig); + } + + @Override + protected MySqlLexer buildLexerInstance(CharStream charStreams) { + return new MySqlLexer(charStreams); + } + + @Override + protected MySqlParser buildParserInstance(CommonTokenStream commonTokenStream) { + return new MySqlParser(commonTokenStream); + } + + @Override + protected ParseTree parseTree(MySqlParser parser) { + return parser.root(); + } + + @Override + protected Antlr4DdlParserListener createParseTreeWalkerListener(DdlParserCallback callback) { + this.callback = callback; + return new MySqlAntlr4DdlParserListener(this); + } + + /** + * Runs the given EventMeshRunner if all the nullableObjects are not null. + * + * @param runner the Runnable to be run + * @param nullableObjects the objects to be checked for null + */ + public void runIfAllNotNull(Runnable runner, Object... nullableObjects) { + // If nullableObjects is null or empty, run the runner + if (nullableObjects == null || nullableObjects.length == 0) { + runner.run(); + } + // Check each nullableObject for null + for (Object nullableObject : nullableObjects) { + // If any nullableObject is null, return without running the runner + if (nullableObject == null) { + return; + } + } + // Run the runner if all nullableObjects are not null + runner.run(); + } + + /** + * Parses a table ID from the given full ID text. + * + * @param fullIdText The full ID text. + * @return The parsed TableId object. + */ + public TableId parseTableId(String fullIdText) { + // Remove special characters from the full ID text + String sanitizedText = StringUtils.replaceEach(fullIdText, new String[]{"'\\''", "\"", "`"}, new String[]{"", "", ""}); + + // Split the sanitized text by dot (.) to separate catalog and table name + String[] split = sanitizedText.split("\\."); + + TableId tableId = new TableId(); + + // Set the table name if there is no catalog specified + if (split.length == 1) { + tableId.setTableName(split[0]); + } else { + // Set the catalog and table name if both are specified + tableId.setCatalogName(split[0]); + tableId.setTableName(split[1]); + } + + return tableId; + } + + public DdlParserCallback getCallback() { + return callback; + } + + public void handleEvent(Event event) { + if (callback != null) { + callback.handle(event); + } + } + + public boolean includeTableId(TableId tableId) { + return includeDatabaseTable.contains(tableId); + } + + public void addTableIdSet(Set tableIdSet) { + if (CollectionUtils.isEmpty(tableIdSet)) { + return; + } + this.includeDatabaseTable.addAll(tableIdSet); + } + + public JdbcSourceConfig getSourceConfig() { + return sourceConfig; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/ColumnDefinitionParserListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/ColumnDefinitionParserListener.java new file mode 100644 index 0000000000..9be9b42ddd --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/ColumnDefinitionParserListener.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. + */ + +package org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.listener; + +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.AutoIncrementColumnConstraintContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.CollateColumnConstraintContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.ColumnDefinitionContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.CommentColumnConstraintContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.NullNotnullContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.PrimaryKeyColumnConstraintContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.UniqueKeyColumnConstraintContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParserBaseListener; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlDataTypeConvertor; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableEditor; +import org.apache.eventmesh.connector.jdbc.table.catalog.mysql.MysqlColumnEditor; +import org.apache.eventmesh.connector.jdbc.table.type.EventMeshDataType; +import org.apache.eventmesh.connector.jdbc.utils.JdbcStringUtils; + +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import org.antlr.v4.runtime.tree.ParseTreeListener; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ColumnDefinitionParserListener extends MySqlParserBaseListener { + + private DefaultValueParserListener defaultValueParserListener; + + private final List listeners; + + private TableEditor tableEditor; + + private MysqlColumnEditor columnEditor; + + private final MysqlAntlr4DdlParser parser; + + private MysqlDataTypeConvertor dataTypeConvertor; + + // Determines whether the current column definition should be ignored. e.g. PRIMARY KEY, UNIQUE KEY + private AtomicReference ignoreColumn = new AtomicReference<>(false); + + public ColumnDefinitionParserListener(List listeners, TableEditor tableEditor, MysqlColumnEditor columnEditor, + MysqlAntlr4DdlParser parser) { + this.listeners = listeners; + this.tableEditor = tableEditor; + this.columnEditor = columnEditor; + this.parser = parser; + this.dataTypeConvertor = new MysqlDataTypeConvertor(); + } + + @Override + public void enterColumnDefinition(ColumnDefinitionContext ctx) { + // parse Column data type + this.parser.runIfAllNotNull(() -> { + String dataTypeString = ctx.dataType().getText(); + EventMeshDataType eventMeshType = this.dataTypeConvertor.toEventMeshType(dataTypeString); + this.columnEditor.withEventMeshType(eventMeshType); + this.columnEditor.withJdbcType(this.dataTypeConvertor.toJDBCType(dataTypeString)); + this.columnEditor.withType(dataTypeString); + }, columnEditor); + + this.parser.runIfAllNotNull(() -> { + // parse column default value + ColumnDefinitionParserListener.this.defaultValueParserListener = new DefaultValueParserListener(columnEditor); + ColumnDefinitionParserListener.this.listeners.add(defaultValueParserListener); + }, tableEditor, columnEditor); + + super.enterColumnDefinition(ctx); + } + + @Override + public void enterNullNotnull(NullNotnullContext ctx) { + columnEditor.notNull(ctx.NOT() != null); + super.enterNullNotnull(ctx); + } + + @Override + public void enterAutoIncrementColumnConstraint(AutoIncrementColumnConstraintContext ctx) { + columnEditor.autoIncremented(true); + columnEditor.generated(true); + super.enterAutoIncrementColumnConstraint(ctx); + } + + @Override + public void enterCommentColumnConstraint(CommentColumnConstraintContext ctx) { + if (ctx.COMMENT() != null && ctx.STRING_LITERAL() != null) { + columnEditor.comment(JdbcStringUtils.withoutWrapper(ctx.STRING_LITERAL().getText())); + } + super.enterCommentColumnConstraint(ctx); + } + + @Override + public void enterPrimaryKeyColumnConstraint(PrimaryKeyColumnConstraintContext ctx) { + /** + * sql example: `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, + */ + ignoreColumn.set(false); + this.tableEditor.withPrimaryKeyNames(this.columnEditor.ofName()); + super.enterPrimaryKeyColumnConstraint(ctx); + } + + @Override + public void enterUniqueKeyColumnConstraint(UniqueKeyColumnConstraintContext ctx) { + ignoreColumn.set(false); + super.enterUniqueKeyColumnConstraint(ctx); + } + + @Override + @SuppressWarnings("unchecked") + public void exitColumnDefinition(ColumnDefinitionContext ctx) { + if (!ignoreColumn.get().booleanValue()) { + this.ignoreColumn.set(false); + } + + // When exit column definition needs to remove DefaultValueParserListener from listener list + parser.runIfAllNotNull(() -> listeners.remove(defaultValueParserListener), tableEditor); + super.exitColumnDefinition(ctx); + } + + @Override + public void enterCollateColumnConstraint(CollateColumnConstraintContext ctx) { + if (ctx.COLLATE() != null) { + columnEditor.collate(ctx.collationName().getText()); + } + super.enterCollateColumnConstraint(ctx); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/CreateDatabaseParserListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/CreateDatabaseParserListener.java new file mode 100644 index 0000000000..a5d15820a9 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/CreateDatabaseParserListener.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.connector.jdbc.source.dialect.antlr4.mysql.listener; + +import org.apache.eventmesh.connector.jdbc.CatalogChanges; +import org.apache.eventmesh.connector.jdbc.Payload; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.CreateDatabaseContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.CreateDatabaseOptionContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParserBaseListener; +import org.apache.eventmesh.connector.jdbc.event.CreateDatabaseEvent; +import org.apache.eventmesh.connector.jdbc.event.SchemaChangeEventType; +import org.apache.eventmesh.connector.jdbc.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlSourceMateData; +import org.apache.eventmesh.connector.jdbc.table.catalog.CatalogSchema; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.utils.Antlr4Utils; +import org.apache.eventmesh.connector.jdbc.utils.JdbcStringUtils; + +/** + * Listener for parsing create database statements using ANTLR4. + *

+ * Mysql CREATE DATABASE Statement: + *

+ *  CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
+ *     [create_option] ...
+ *  create_option: [DEFAULT] {
+ *     CHARACTER SET [=] charset_name
+ *   | COLLATE [=] collation_name
+ *   | ENCRYPTION [=] {'Y' | 'N'}
+ * }
+ * 
+ */ +public class CreateDatabaseParserListener extends MySqlParserBaseListener { + + private String databaseName; + + private String charSetName; + + private String collate; + + private String encryption; + + private MysqlAntlr4DdlParser parser; + + public CreateDatabaseParserListener(MysqlAntlr4DdlParser parser) { + this.parser = parser; + } + + @Override + public void enterCreateDatabase(CreateDatabaseContext ctx) { + this.databaseName = JdbcStringUtils.withoutWrapper(ctx.uid().getText()); + super.enterCreateDatabase(ctx); + } + + @Override + public void exitCreateDatabase(CreateDatabaseContext ctx) { + if (parser.getCallback() != null) { + String sql = Antlr4Utils.getText(ctx); + CatalogSchema catalogSchema = new CatalogSchema(databaseName, charSetName); + CreateDatabaseEvent event = new CreateDatabaseEvent(new TableId(databaseName)); + Payload payload = event.getJdbcConnectData().getPayload(); + SourceConnectorConfig sourceConnectorConfig = parser.getSourceConfig().getSourceConnectorConfig(); + MysqlSourceMateData sourceMateData = MysqlSourceMateData.newBuilder() + .name(sourceConnectorConfig.getName()) + .catalogName(databaseName) + .serverId(sourceConnectorConfig.getMysqlConfig().getServerId()) + .build(); + CatalogChanges changes = CatalogChanges.newBuilder().operationType(SchemaChangeEventType.DATABASE_CREATE).catalog(catalogSchema).build(); + payload.withSource(sourceMateData).withDdl(sql).withCatalogChanges(changes); + parser.getCallback().handle(event); + } + super.exitCreateDatabase(ctx); + } + + @Override + public void enterCreateDatabaseOption(CreateDatabaseOptionContext ctx) { + this.charSetName = ctx.charsetName().getText(); + this.collate = ctx.COLLATE().getText(); + this.encryption = ctx.ENCRYPTION().getText(); + super.enterCreateDatabaseOption(ctx); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/CreateTableParserListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/CreateTableParserListener.java new file mode 100644 index 0000000000..5a72c4449b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/CreateTableParserListener.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.connector.jdbc.source.dialect.antlr4.mysql.listener; + +import org.apache.eventmesh.connector.jdbc.CatalogChanges; +import org.apache.eventmesh.connector.jdbc.Payload; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.ColumnCreateTableContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.CopyCreateTableContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.QueryCreateTableContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.TableOptionCharsetContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.TableOptionCollateContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.TableOptionEngineContext; +import org.apache.eventmesh.connector.jdbc.event.CreateTableEvent; +import org.apache.eventmesh.connector.jdbc.event.SchemaChangeEventType; +import org.apache.eventmesh.connector.jdbc.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlSourceMateData; +import org.apache.eventmesh.connector.jdbc.table.catalog.Table; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.table.catalog.mysql.MysqlTableEditor; +import org.apache.eventmesh.connector.jdbc.table.catalog.mysql.MysqlTableOptions; +import org.apache.eventmesh.connector.jdbc.table.catalog.mysql.MysqlTableSchema; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + *
+ * listen for events while parsing a CREATE TABLE statement in a MySQL DDL (Data Definition Language) script.
+ * 
+ * + * MYSQL CREATE TABLE + * + *
+ * CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
+ *     (create_definition,...)
+ *     [table_options]
+ *     [partition_options]
+ * 
+ * + *
+ * CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
+ *     [(create_definition,...)]
+ *     [table_options]
+ *     [partition_options]
+ *     [IGNORE | REPLACE]
+ *     [AS] query_expression
+ * 
+ *
+ * CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
+ *     { LIKE old_tbl_name | (LIKE old_tbl_name) }
+ * 
+ */ +public class CreateTableParserListener extends TableBaseParserListener { + + public CreateTableParserListener(List listeners, MysqlAntlr4DdlParser parser) { + super(listeners, parser); + } + + @Override + public void enterCopyCreateTable(CopyCreateTableContext ctx) { + // TODO support next version + super.enterCopyCreateTable(ctx); + } + + @Override + public void enterQueryCreateTable(QueryCreateTableContext ctx) { + // TODO support next version + super.enterQueryCreateTable(ctx); + } + + @Override + public void enterColumnCreateTable(ColumnCreateTableContext ctx) { + String tableName = ctx.tableName().fullId().getText(); + this.tableEditor = createTableEditor(tableName); + super.enterColumnCreateTable(ctx); + } + + @Override + public void exitColumnCreateTable(ColumnCreateTableContext ctx) { + String ddl = ctx.getText(); + parser.runIfAllNotNull(() -> { + listeners.remove(columnDefinitionListener); + // help JVM GC + columnDefinitionListener = null; + MysqlTableSchema tableSchema = tableEditor.build(); + parser.getCatalogTableSet().overrideTable(tableSchema); + String currentDatabase = parser.getCurrentDatabase(); + CreateTableEvent event = new CreateTableEvent(new TableId(currentDatabase, null, tableSchema.getSimpleName())); + Payload payload = event.getJdbcConnectData().getPayload(); + SourceConnectorConfig sourceConnectorConfig = parser.getSourceConfig().getSourceConnectorConfig(); + MysqlSourceMateData sourceMateData = MysqlSourceMateData.newBuilder() + .name(sourceConnectorConfig.getName()) + .catalogName(currentDatabase) + .serverId(sourceConnectorConfig.getMysqlConfig().getServerId()) + .build(); + Table table = new Table(tableSchema.getSimpleName(), tableSchema.getPrimaryKey(), tableSchema.getUniqueKeys(), tableSchema.getComment()); + CatalogChanges changes = CatalogChanges.newBuilder().operationType(SchemaChangeEventType.TABLE_CREATE).table(table) + .columns(tableSchema.getColumns()).build(); + payload.withSource(sourceMateData).withDdl(ddl).withCatalogChanges(changes); + parser.handleEvent(event); + }, tableEditor); + // reset column order + columnOrder.set(1); + super.exitColumnCreateTable(ctx); + } + + private MysqlTableEditor createTableEditor(String tableName) { + TableId tableId = parser.parseTableId(tableName); + if (StringUtils.isBlank(tableId.getCatalogName())) { + tableId.setCatalogName(parser.getCurrentDatabase()); + } + return MysqlTableEditor.ofCatalogTableEditor(tableId); + } + + @Override + public void enterTableOptionEngine(TableOptionEngineContext ctx) { + if (ctx.ENGINE() != null) { + this.tableEditor.withOption(MysqlTableOptions.ENGINE, ctx.ENGINE().getText()); + } + super.enterTableOptionEngine(ctx); + } + + @Override + public void enterTableOptionCharset(TableOptionCharsetContext ctx) { + + List nodes = ctx.DEFAULT(); + if (CollectionUtils.isNotEmpty(nodes) && nodes.size() == 2) { + TerminalNode node = nodes.get(1); + this.tableEditor.withOption(MysqlTableOptions.CHARSET, node.getText()); + } else { + this.tableEditor.withOption(MysqlTableOptions.CHARSET, ctx.charsetName().getText()); + } + + super.enterTableOptionCharset(ctx); + } + + @Override + public void enterTableOptionCollate(TableOptionCollateContext ctx) { + if (ctx.COLLATE() != null) { + this.tableEditor.withOption(MysqlTableOptions.COLLATE, ctx.collationName().getText()); + } + super.enterTableOptionCollate(ctx); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/DefaultValueParserListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/DefaultValueParserListener.java new file mode 100644 index 0000000000..aad1dc65ad --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/DefaultValueParserListener.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.source.dialect.antlr4.mysql.listener; + +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.CurrentTimestampContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.DefaultValueContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.StringLiteralContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParserBaseListener; +import org.apache.eventmesh.connector.jdbc.table.catalog.mysql.MysqlColumnEditor; + +import org.apache.commons.collections4.CollectionUtils; + +import java.util.List; + +/** + * Listener for parsing default values in MySQL parser. + */ +public class DefaultValueParserListener extends MySqlParserBaseListener { + + private final MysqlColumnEditor columnEditor; + + public DefaultValueParserListener(MysqlColumnEditor columnEditor) { + this.columnEditor = columnEditor; + } + + @Override + public void enterDefaultValue(DefaultValueContext ctx) { + + /** + * defaultValue + * : NULL_LITERAL + * | CAST '(' expression AS convertedDataType ')' + * | unaryOperator? constant + * | currentTimestamp (ON UPDATE currentTimestamp)? + * | '(' expression ')' + * | '(' fullId ')' + * ; + */ + String sign = ""; + + // Default value is NULL + if (ctx.NULL_LITERAL() != null) { + return; + } + + if (ctx.CAST() != null && ctx.expression() != null) { + columnEditor.defaultValueExpression(ctx.getText()); + return; + } + + if (ctx.unaryOperator() != null) { + sign = ctx.unaryOperator().getText(); + } + + /** + * Process expression + * constant + * : stringLiteral | decimalLiteral + * | '-' decimalLiteral + * | hexadecimalLiteral | booleanLiteral + * | REAL_LITERAL | BIT_STRING + * | NOT? nullLiteral=(NULL_LITERAL | NULL_SPEC_LITERAL) + * ; + */ + if (ctx.constant() != null) { + StringLiteralContext stringLiteralContext = ctx.constant().stringLiteral(); + if (stringLiteralContext != null) { + if (stringLiteralContext.COLLATE() == null) { + columnEditor.defaultValueExpression(sign + unquote(stringLiteralContext.getText())); + } else { + columnEditor.collate(sign + unquote(stringLiteralContext.STRING_LITERAL(0).getText())); + } + } else if (ctx.constant().decimalLiteral() != null) { + columnEditor.defaultValueExpression(sign + ctx.constant().decimalLiteral().getText()); + } else if (ctx.constant().BIT_STRING() != null) { + columnEditor.defaultValueExpression(unquoteBinary(ctx.constant().BIT_STRING().getText())); + } else if (ctx.constant().booleanLiteral() != null) { + columnEditor.defaultValueExpression(ctx.constant().booleanLiteral().getText()); + } else if (ctx.constant().REAL_LITERAL() != null) { + columnEditor.defaultValueExpression(ctx.constant().REAL_LITERAL().getText()); + } + } else if (CollectionUtils.isNotEmpty(ctx.currentTimestamp())) { + + /** + * timestamp-initialization + * cast-functions + * defaultValue + * : NULL_LITERAL + * | CAST '(' expression AS convertedDataType ')' + * | unaryOperator? constant + * | currentTimestamp (ON UPDATE currentTimestamp)? + * | '(' expression ')' + * | '(' fullId ')' + * ; + * currentTimestamp + * : + * ( + * (CURRENT_TIMESTAMP | LOCALTIME | LOCALTIMESTAMP) + * ('(' decimalLiteral? ')')? + * | NOW '(' decimalLiteral? ')' + * ) + * ; + */ + List currentTimestampContexts = ctx.currentTimestamp(); + if (currentTimestampContexts.size() > 1 || (ctx.ON() == null && ctx.UPDATE() == null)) { + CurrentTimestampContext currentTimestampContext = currentTimestampContexts.get(0); + // + if (currentTimestampContext.CURRENT_TIMESTAMP() != null || currentTimestampContext.NOW() != null) { + columnEditor.defaultValueExpression("1970-01-01 00:00:00"); + } else { + columnEditor.defaultValueExpression(currentTimestampContext.getText()); + } + } + } else if (ctx.expression() != null) { + // e.g. CREATE TABLE t2 (b BLOB DEFAULT ('abc')); + columnEditor.defaultValueExpression(ctx.expression().getText()); + } else if (ctx.fullId() != null) { + columnEditor.defaultValueExpression(ctx.expression().getText()); + } + super.enterDefaultValue(ctx); + } + + @Override + public void exitDefaultValue(DefaultValueContext ctx) { + super.exitDefaultValue(ctx); + } + + private String unquote(String stringLiteral) { + if (stringLiteral != null && ((stringLiteral.startsWith("'") && stringLiteral.endsWith("'")) + || (stringLiteral.startsWith("\"") && stringLiteral.endsWith("\"")))) { + return stringLiteral.substring(1, stringLiteral.length() - 1); + } + return stringLiteral; + } + + private String unquoteBinary(String stringLiteral) { + return stringLiteral.substring(2, stringLiteral.length() - 1); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/DropDatabaseParserListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/DropDatabaseParserListener.java new file mode 100644 index 0000000000..22a25fcd32 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/DropDatabaseParserListener.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.connector.jdbc.source.dialect.antlr4.mysql.listener; + +import org.apache.eventmesh.connector.jdbc.CatalogChanges; +import org.apache.eventmesh.connector.jdbc.Payload; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.DropDatabaseContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParserBaseListener; +import org.apache.eventmesh.connector.jdbc.event.DropDatabaseEvent; +import org.apache.eventmesh.connector.jdbc.event.SchemaChangeEventType; +import org.apache.eventmesh.connector.jdbc.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlSourceMateData; +import org.apache.eventmesh.connector.jdbc.table.catalog.CatalogSchema; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.utils.Antlr4Utils; +import org.apache.eventmesh.connector.jdbc.utils.JdbcStringUtils; + +public class DropDatabaseParserListener extends MySqlParserBaseListener { + + private MysqlAntlr4DdlParser parser; + + public DropDatabaseParserListener(MysqlAntlr4DdlParser parser) { + this.parser = parser; + } + + @Override + public void enterDropDatabase(DropDatabaseContext ctx) { + + String databaseName = JdbcStringUtils.withoutWrapper(ctx.uid().getText()); + parser.getCatalogTableSet().removeDatabase(databaseName); + if (parser.getCallback() != null) { + String sql = Antlr4Utils.getText(ctx); + CatalogSchema catalogSchema = new CatalogSchema(databaseName); + DropDatabaseEvent event = new DropDatabaseEvent(new TableId(databaseName)); + Payload payload = event.getJdbcConnectData().getPayload(); + SourceConnectorConfig sourceConnectorConfig = parser.getSourceConfig().getSourceConnectorConfig(); + MysqlSourceMateData sourceMateData = MysqlSourceMateData.newBuilder() + .name(sourceConnectorConfig.getName()) + .catalogName(databaseName) + .serverId(sourceConnectorConfig.getMysqlConfig().getServerId()) + .build(); + CatalogChanges changes = CatalogChanges.newBuilder().operationType(SchemaChangeEventType.DATABASE_DROP).catalog(catalogSchema).build(); + payload.withSource(sourceMateData).withDdl(sql).withCatalogChanges(changes); + parser.getCallback().handle(event); + } + super.enterDropDatabase(ctx); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/MySqlAntlr4DdlParserListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/MySqlAntlr4DdlParserListener.java new file mode 100644 index 0000000000..8049c6b2d0 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/MySqlAntlr4DdlParserListener.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.jdbc.source.dialect.antlr4.mysql.listener; + +import org.apache.eventmesh.connector.jdbc.antlr4.listener.Antlr4DdlParserListener; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.TerminalNode; + +public class MySqlAntlr4DdlParserListener implements Antlr4DdlParserListener { + + private final List listeners = new CopyOnWriteArrayList<>(); + + public MySqlAntlr4DdlParserListener(MysqlAntlr4DdlParser parser) { + listeners.add(new CreateDatabaseParserListener(parser)); + listeners.add(new DropDatabaseParserListener(parser)); + listeners.add(new CreateTableParserListener(listeners, parser)); + listeners.add(new TruncateTableParserListener(parser)); + } + + @Override + public void visitTerminal(TerminalNode node) { + for (ParseTreeListener listener : listeners) { + listener.visitTerminal(node); + } + } + + @Override + public void visitErrorNode(ErrorNode node) { + for (ParseTreeListener listener : listeners) { + listener.visitErrorNode(node); + } + } + + @Override + public void enterEveryRule(ParserRuleContext ctx) { + + for (ParseTreeListener listener : listeners) { + listener.enterEveryRule(ctx); + ctx.enterRule(listener); + } + } + + @Override + public void exitEveryRule(ParserRuleContext ctx) { + for (ParseTreeListener listener : listeners) { + ctx.exitRule(listener); + listener.exitEveryRule(ctx); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/TableBaseParserListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/TableBaseParserListener.java new file mode 100644 index 0000000000..3789cbf6f9 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/TableBaseParserListener.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.connector.jdbc.source.dialect.antlr4.mysql.listener; + +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.ColumnDeclarationContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.DottedIdContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.FullColumnNameContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.IndexColumnNamesContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.IndexOptionContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.PrimaryKeyTableConstraintContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.UidContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.UniqueKeyTableConstraintContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParserBaseListener; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; +import org.apache.eventmesh.connector.jdbc.table.catalog.mysql.MysqlColumnEditor; +import org.apache.eventmesh.connector.jdbc.table.catalog.mysql.MysqlTableEditor; +import org.apache.eventmesh.connector.jdbc.utils.JdbcStringUtils; + +import org.apache.commons.collections4.CollectionUtils; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +import org.antlr.v4.runtime.tree.ParseTreeListener; + +public class TableBaseParserListener extends MySqlParserBaseListener { + + protected final List listeners; + + protected final MysqlAntlr4DdlParser parser; + + protected MysqlTableEditor tableEditor; + + protected ColumnDefinitionParserListener columnDefinitionListener; + + protected AtomicInteger columnOrder = new AtomicInteger(1); + + public TableBaseParserListener(List listeners, MysqlAntlr4DdlParser parser) { + this.listeners = listeners; + this.parser = parser; + } + + /** + * Called when entering a column declaration context. + * + * @param ctx The column declaration context. + */ + @Override + public void enterColumnDeclaration(ColumnDeclarationContext ctx) { + + /** + * Parse + * createDefinition + * : fullColumnName columnDefinition #columnDeclaration + * | tableConstraint NOT? ENFORCED? #constraintDeclaration + * | indexColumnDefinition #indexDeclaration + * ; + */ + parser.runIfAllNotNull(() -> { + FullColumnNameContext fullColumnNameContext = ctx.fullColumnName(); + // parse column name + UidContext uidContext = fullColumnNameContext.uid(); + List dottedIdContextList = fullColumnNameContext.dottedId(); + if (CollectionUtils.isNotEmpty(dottedIdContextList)) { + uidContext = dottedIdContextList.get(dottedIdContextList.size() - 1).uid(); + } + String columnName = JdbcStringUtils.withoutWrapper(uidContext.getText()); + MysqlColumnEditor columnEditor = MysqlColumnEditor.ofEditor(columnName); + if (Objects.isNull(columnDefinitionListener)) { + columnDefinitionListener = new ColumnDefinitionParserListener(listeners, tableEditor, columnEditor, parser); + // add ColumnDefinitionParserListener to listener list + listeners.add(columnDefinitionListener); + } else { + columnDefinitionListener.setColumnEditor(columnEditor); + } + }, tableEditor); + + super.enterColumnDeclaration(ctx); + } + + @Override + public void exitColumnDeclaration(ColumnDeclarationContext ctx) { + + parser.runIfAllNotNull(() -> { + MysqlColumnEditor columnEditor = columnDefinitionListener.getColumnEditor(); + columnEditor.withOrder(columnOrder.getAndIncrement()); + tableEditor.addColumns(columnEditor.build()); + }, tableEditor, columnDefinitionListener); + + super.exitColumnDeclaration(ctx); + } + + @Override + public void enterPrimaryKeyTableConstraint(PrimaryKeyTableConstraintContext ctx) { + /** + *Although the creation of a Primary Key is defined within the column definitions when creating a table, + * it can be considered as part of table management in practice. + * SQL example: PRIMARY KEY (`id`), + */ + parser.runIfAllNotNull(() -> { + IndexColumnNamesContext indexColumnNamesContext = ctx.indexColumnNames(); + List pkColumnNames = indexColumnNamesContext.indexColumnName().stream().map(indexColumnNameCtx -> { + /** + * indexColumnName + * : ((uid | STRING_LITERAL) ('(' decimalLiteral ')')? | expression) sortType=(ASC | DESC)? + * + */ + String pkColumnName; + if (indexColumnNameCtx.uid() != null) { + pkColumnName = JdbcStringUtils.withoutWrapper(indexColumnNameCtx.uid().getText()); + } else if (indexColumnNameCtx.STRING_LITERAL() != null) { + pkColumnName = JdbcStringUtils.withoutWrapper(indexColumnNameCtx.STRING_LITERAL().getText()); + } else { + pkColumnName = indexColumnNameCtx.expression().getText(); + } + return pkColumnName; + }).collect(Collectors.toList()); + String comment = null; + List indexOptionContexts = ctx.indexOption(); + for (IndexOptionContext indexOptionContext : indexOptionContexts) { + if (indexOptionContext.COMMENT() != null && indexOptionContext.STRING_LITERAL() != null) { + comment = indexOptionContext.STRING_LITERAL().getText(); + } + } + tableEditor.withPrimaryKeyNames(pkColumnNames, comment); + }, tableEditor); + + super.enterPrimaryKeyTableConstraint(ctx); + } + + @Override + public void enterUniqueKeyTableConstraint(UniqueKeyTableConstraintContext ctx) { + + // sql example: UNIQUE KEY `eventmesh` (`event_mesh`) USING BTREE COMMENT 'event mesh' + + parser.runIfAllNotNull(() -> { + IndexColumnNamesContext indexColumnNamesContext = ctx.indexColumnNames(); + List ukColumnNames = indexColumnNamesContext.indexColumnName().stream().map(indexColumnNameCtx -> { + /** + * indexColumnName + * : ((uid | STRING_LITERAL) ('(' decimalLiteral ')')? | expression) sortType=(ASC | DESC)? + * + */ + String ukColumnName; + if (indexColumnNameCtx.uid() != null) { + ukColumnName = JdbcStringUtils.withoutWrapper(indexColumnNameCtx.uid().getText()); + } else if (indexColumnNameCtx.STRING_LITERAL() != null) { + ukColumnName = JdbcStringUtils.withoutWrapper(indexColumnNameCtx.STRING_LITERAL().getText()); + } else { + ukColumnName = indexColumnNameCtx.expression().getText(); + } + return ukColumnName; + }).collect(Collectors.toList()); + List indexOptionContexts = ctx.indexOption(); + String comment = null; + if (CollectionUtils.isNotEmpty(indexOptionContexts)) { + for (IndexOptionContext context : indexOptionContexts) { + if (context.COMMENT() != null && context.STRING_LITERAL() != null) { + comment = context.STRING_LITERAL().getText(); + } + } + } + String ukName = ctx.index != null ? ctx.index.getText() : null; + tableEditor.withUniqueKeyColumnsNames(ukName, ukColumnNames, comment); + }, tableEditor); + + super.enterUniqueKeyTableConstraint(ctx); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/TruncateTableParserListener.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/TruncateTableParserListener.java new file mode 100644 index 0000000000..ab4a674e64 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/antlr4/mysql/listener/TruncateTableParserListener.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.connector.jdbc.source.dialect.antlr4.mysql.listener; + +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParser.TruncateTableContext; +import org.apache.eventmesh.connector.jdbc.antlr4.autogeneration.MySqlParserBaseListener; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; +import org.apache.eventmesh.connector.jdbc.utils.Antlr4Utils; +import org.apache.eventmesh.connector.jdbc.utils.JdbcStringUtils; + +/** + * A custom ANTLR listener for parsing TRUNCATE TABLE statements. + * TRUNCATE TABLE Statement + *
+ *     TRUNCATE [TABLE] tbl_name
+ * 
+ */ +public class TruncateTableParserListener extends MySqlParserBaseListener { + + private MysqlAntlr4DdlParser parser; + + /** + * Constructs a TruncateTableParserListener with the specified parser. + * + * @param parser The MysqlAntlr4DdlParser used for parsing. + */ + public TruncateTableParserListener(MysqlAntlr4DdlParser parser) { + this.parser = parser; + } + + @Override + public void enterTruncateTable(TruncateTableContext ctx) { + String sql = Antlr4Utils.getText(ctx); + String tableName = JdbcStringUtils.withoutWrapper(ctx.tableName().fullId().getText()); + // TruncateTableEvent event = new TruncateTableEvent(parser.getCurrentDatabase(), tableName, sql); + parser.handleEvent(null); + super.enterTruncateTable(ctx); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/AbstractCdcEngine.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/AbstractCdcEngine.java new file mode 100644 index 0000000000..fc9d2f3724 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/AbstractCdcEngine.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.connector.jdbc.source.dialect.cdc; + +import org.apache.eventmesh.common.ThreadWrapper; +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.connector.jdbc.JdbcContext; +import org.apache.eventmesh.connector.jdbc.ddl.DdlParser; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import org.apache.commons.collections4.CollectionUtils; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractCdcEngine extends + ThreadWrapper implements CdcEngine { + + protected final JdbcSourceConfig jdbcSourceConfig; + + protected final DbDialect databaseDialect; + + protected final SourceConnectorConfig sourceConnectorConfig; + + private final Set includeDatabaseTable = new HashSet<>(64); + + public AbstractCdcEngine(SourceConfig config, DbDialect databaseDialect) { + if (!(config instanceof JdbcSourceConfig)) { + throw new IllegalArgumentException("config "); + } + this.jdbcSourceConfig = (JdbcSourceConfig) config; + this.databaseDialect = databaseDialect; + this.sourceConnectorConfig = this.jdbcSourceConfig.getSourceConnectorConfig(); + + calculateNeedHandleTable(); + } + + @Override + public Set getHandledTables() { + return includeDatabaseTable; + } + + protected Set calculateNeedHandleTable() { + // Get the database and table include and exclude lists from the connector configuration + List databaseIncludeList = sourceConnectorConfig.getDatabaseIncludeList(); + + // If the database include list is empty, get a list of all databases and use that as the include list + if (CollectionUtils.isEmpty(databaseIncludeList)) { + List allDatabases = databaseDialect.listDatabases(); + databaseIncludeList = new ArrayList<>(allDatabases); + } + Set defaultExcludeDatabase = defaultExcludeDatabase(); + if (CollectionUtils.isNotEmpty(defaultExcludeDatabase)) { + databaseIncludeList.removeAll(defaultExcludeDatabase); + } + + List databaseExcludeList = sourceConnectorConfig.getDatabaseExcludeList(); + // Remove the default excluded databases from the include list + if (CollectionUtils.isNotEmpty(databaseExcludeList)) { + databaseIncludeList.removeAll(databaseExcludeList); + } + + List tableIncludeList = sourceConnectorConfig.getTableIncludeList(); + // Create a list of included tables based on the table include list + List includeTableList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(tableIncludeList)) { + List tableIdList = buildTableId(tableIncludeList); + includeTableList.addAll(tableIdList); + } + + // If the table include list is empty, get a list of all tables for each database in the include list + if (CollectionUtils.isEmpty(tableIncludeList)) { + for (String database : databaseIncludeList) { + try { + List tableIds = databaseDialect.listTables(database); + includeTableList.addAll(tableIds); + } catch (SQLException e) { + log.warn("List database[{}] table error", database, e); + } + } + } + + List tableExcludeList = sourceConnectorConfig.getTableExcludeList(); + // Remove any tables in the exclude list from the included tables list + if (CollectionUtils.isNotEmpty(tableExcludeList)) { + includeTableList.removeAll(buildTableId(tableExcludeList)); + } + + includeDatabaseTable.addAll(includeTableList); + + return includeDatabaseTable; + } + + private List buildTableId(List tables) { + return Optional.ofNullable(tables).orElse(new ArrayList<>(0)).stream().map(table -> { + String[] split = table.split("\\."); + return new TableId(split[0], null, split[1]); + }).collect(Collectors.toList()); + } + + protected abstract Set defaultExcludeDatabase(); + + protected abstract Parse getDdlParser(); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/AbstractCdcEngineFactory.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/AbstractCdcEngineFactory.java new file mode 100644 index 0000000000..d00d4c56fa --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/AbstractCdcEngineFactory.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.connector.jdbc.source.dialect.cdc; + +public abstract class AbstractCdcEngineFactory implements CdcEngineFactory { + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/CdcEngine.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/CdcEngine.java new file mode 100644 index 0000000000..566ffccf4c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/CdcEngine.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.connector.jdbc.source.dialect.cdc; + +import org.apache.eventmesh.connector.jdbc.JdbcContext; +import org.apache.eventmesh.connector.jdbc.event.EventConsumer; +import org.apache.eventmesh.connector.jdbc.source.Engine; + +/** + * CdcEngine is a service that captures data change events. + */ +public interface CdcEngine extends Engine, AutoCloseable { + + /** + * Stops the CDC Engine. + */ + @Override + void close() throws Exception; + + /** + * Returns the name of the CDC Engine. + * + * @return String representing the name of the CDC Engine. + */ + String getCdcEngineName(); + + /** + * Registers the CDC event consumer. + * + * @param consumer The CDC event consumer to register. + */ + void registerCdcEventConsumer(EventConsumer consumer); + + void setContext(Context context); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/CdcEngineFactory.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/CdcEngineFactory.java new file mode 100644 index 0000000000..33e5f555b6 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/CdcEngineFactory.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.connector.jdbc.source.dialect.cdc; + +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.openconnect.api.config.SourceConfig; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +/** + * This interface defines the methods required to create a Change Data Capture (CDC) engine + */ +@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.JDBC_CDC_ENGINE) +public interface CdcEngineFactory { + + /** + * Determines whether the provided JDBC URL is compatible with the CDC engine + * + * @param url jdbc url, e.g. mysql: jdbc:mysql://localhost:3306/ + * @return true if the JDBC URL is compatible with the CDC engine, false otherwise + */ + boolean acceptJdbcProtocol(String url); + + /** + * Creates a CDC engine based on the provided source configuration and database dialect. + * + * @param config the source configuration for the CDC engine + * @param databaseDialect the database dialect for the CDC engine + * @return the created CDC engine + */ + CdcEngine createCdcEngine(SourceConfig config, DatabaseDialect databaseDialect); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/RandomTaskSelectStrategy.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/RandomTaskSelectStrategy.java new file mode 100644 index 0000000000..4b05d41b31 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/RandomTaskSelectStrategy.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.jdbc.source.dialect.cdc; + +import org.apache.eventmesh.connector.jdbc.source.EventMeshJdbcTask; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import java.util.List; +import java.util.Random; + +public class RandomTaskSelectStrategy implements TaskSelectStrategy { + + private List cdcTasks; + + public RandomTaskSelectStrategy(List cdcTasks) { + this.cdcTasks = cdcTasks; + } + + /** + * Selects a JdbcTask for the specified TableId. + * + * @param tableId the TableId for which to select a JdbcTask + * @return the selected JdbcTask + */ + @Override + public Task select(TableId tableId) { + Random random = new Random(System.currentTimeMillis()); + int randomNum = random.nextInt(cdcTasks.size()); + return cdcTasks.get(randomNum); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/TaskSelectStrategy.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/TaskSelectStrategy.java new file mode 100644 index 0000000000..62e04c0507 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/TaskSelectStrategy.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.connector.jdbc.source.dialect.cdc; + +import org.apache.eventmesh.connector.jdbc.source.EventMeshJdbcTask; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +/** + * Represents a strategy for selecting a CdcTask for a given TableId. + */ +public interface TaskSelectStrategy { + + /** + * Selects a CdcTask for the specified TableId. + * + * @param tableId the TableId for which to select a CdcTask + * @return the selected CdcTask + */ + Task select(TableId tableId); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/mysql/MysqlCdcEngine.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/mysql/MysqlCdcEngine.java new file mode 100644 index 0000000000..67c837caf7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/mysql/MysqlCdcEngine.java @@ -0,0 +1,804 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.source.dialect.cdc.mysql; + +import org.apache.eventmesh.common.EventMeshThreadFactory; +import org.apache.eventmesh.connector.jdbc.DataChanges; +import org.apache.eventmesh.connector.jdbc.DataChanges.Builder; +import org.apache.eventmesh.connector.jdbc.Field; +import org.apache.eventmesh.connector.jdbc.Payload; +import org.apache.eventmesh.connector.jdbc.Schema; +import org.apache.eventmesh.connector.jdbc.config.JdbcConfig; +import org.apache.eventmesh.connector.jdbc.connection.mysql.MysqlJdbcConnection; +import org.apache.eventmesh.connector.jdbc.event.DeleteDataEvent; +import org.apache.eventmesh.connector.jdbc.event.EventConsumer; +import org.apache.eventmesh.connector.jdbc.event.GeneralDataChangeEvent; +import org.apache.eventmesh.connector.jdbc.event.InsertDataEvent; +import org.apache.eventmesh.connector.jdbc.event.UpdateDataEvent; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.config.MysqlConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.AbstractCdcEngine; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.mysql.RowDeserializers.DeleteRowsEventMeshDeserializer; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.mysql.RowDeserializers.UpdateRowsEventMeshDeserializer; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.mysql.RowDeserializers.WriteRowsEventMeshDeserializer; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.EventDataDeserializationExceptionData; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.EventMeshGtidSet; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlConstants; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlDatabaseDialect; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlJdbcContext; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlSourceMateData; +import org.apache.eventmesh.connector.jdbc.table.catalog.Column; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableSchema; +import org.apache.eventmesh.connector.jdbc.table.type.Pair; +import org.apache.eventmesh.openconnect.api.config.Config; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import com.github.shyiko.mysql.binlog.BinaryLogClient; +import com.github.shyiko.mysql.binlog.BinaryLogClient.LifecycleListener; +import com.github.shyiko.mysql.binlog.event.DeleteRowsEventData; +import com.github.shyiko.mysql.binlog.event.Event; +import com.github.shyiko.mysql.binlog.event.EventData; +import com.github.shyiko.mysql.binlog.event.EventHeader; +import com.github.shyiko.mysql.binlog.event.EventHeaderV4; +import com.github.shyiko.mysql.binlog.event.EventType; +import com.github.shyiko.mysql.binlog.event.GtidEventData; +import com.github.shyiko.mysql.binlog.event.QueryEventData; +import com.github.shyiko.mysql.binlog.event.RotateEventData; +import com.github.shyiko.mysql.binlog.event.TableMapEventData; +import com.github.shyiko.mysql.binlog.event.TransactionPayloadEventData; +import com.github.shyiko.mysql.binlog.event.UpdateRowsEventData; +import com.github.shyiko.mysql.binlog.event.WriteRowsEventData; +import com.github.shyiko.mysql.binlog.event.XidEventData; +import com.github.shyiko.mysql.binlog.event.deserialization.EventDataDeserializationException; +import com.github.shyiko.mysql.binlog.event.deserialization.EventDeserializer; +import com.github.shyiko.mysql.binlog.io.ByteArrayInputStream; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MysqlCdcEngine extends AbstractCdcEngine { + + private BinaryLogClient client; + + private BlockingQueue eventQueue = new LinkedBlockingQueue<>(10000); + + private final EnumMap> eventHandlers = new EnumMap<>(EventType.class); + + private Map tableIdMap = new HashMap<>(64); + + private MysqlJdbcContext context; + + private List consumers = new ArrayList<>(16); + + private MysqlAntlr4DdlParser ddlParser; + + private MysqlJdbcConnection connection; + + private com.github.shyiko.mysql.binlog.GtidSet localGtidSet; + + public MysqlCdcEngine(Config config, MysqlDatabaseDialect databaseDialect) { + super((JdbcSourceConfig) config, databaseDialect); + this.ddlParser = new MysqlAntlr4DdlParser(false, false, getHandledTables(), (JdbcSourceConfig) config); + this.connection = databaseDialect.getConnection(); + } + + /** + * Initializes the CDC Engine. + */ + @Override + public void init() { + final JdbcConfig jdbcConfig = this.sourceConnectorConfig.getJdbcConfig(); + client = new BinaryLogClient(jdbcConfig.getHostname(), jdbcConfig.getPort(), jdbcConfig.getUser(), jdbcConfig.getPassword()); + client.setThreadFactory(new EventMeshThreadFactory("mysql-binlog-client")); + final MysqlConfig mysqlConfig = this.sourceConnectorConfig.getMysqlConfig(); + client.setServerId(mysqlConfig.getServerId()); + client.setKeepAlive(mysqlConfig.isKeepAlive()); + final long keepAliveInterval = mysqlConfig.getKeepAliveInterval(); + client.setKeepAliveInterval(keepAliveInterval); + + final Map tableMapEventByTableId = new HashMap<>(32); + + // mysql dev url:https://dev.mysql.com/doc/dev/mysql-server/latest/ + EventDeserializer eventDeserializer = new EventDeserializer() { + + /** + * @param inputStream input stream to fetch event from + * @return deserialized event or null in case of end-of-stream + * @throws IOException if connection gets closed + */ + @Override + public Event nextEvent(ByteArrayInputStream inputStream) throws IOException { + try { + // Delegate to the superclass + Event event = super.nextEvent(inputStream); + log.debug("MYSQL Binlog---EventType={}, EventData={}", event.getHeader().getEventType(), event); + // We have to record the most recent TableMapEventData for each table number for our custom deserializers + if (event.getHeader().getEventType() == EventType.TABLE_MAP) { + TableMapEventData tableMapEvent = event.getData(); + tableMapEventByTableId.put(tableMapEvent.getTableId(), tableMapEvent); + } + + // Handle for transaction payload and capture the table map event and add it to the map + if (event.getHeader().getEventType() == EventType.TRANSACTION_PAYLOAD) { + TransactionPayloadEventData transactionPayloadEventData = event.getData(); + /** + * Loop over the uncompressed events in the transaction payload event and add the table map + * event in the map of table events + **/ + for (Event uncompressedEvent : transactionPayloadEventData.getUncompressedEvents()) { + if (uncompressedEvent.getHeader().getEventType() == EventType.TABLE_MAP && uncompressedEvent.getData() != null) { + TableMapEventData tableMapEvent = uncompressedEvent.getData(); + tableMapEventByTableId.put(tableMapEvent.getTableId(), tableMapEvent); + } + } + } + // Clean cache on rotate event to prevent it from growing indefinitely. + if (event.getHeader().getEventType() == EventType.ROTATE) { + tableMapEventByTableId.clear(); + } + return event; + } catch (EventDataDeserializationException ex) { + if (ex.getCause() instanceof IOException) { + throw ex; + } + EventHeaderV4 header = new EventHeaderV4(); + header.setEventType(EventType.INCIDENT); + header.setTimestamp(ex.getEventHeader().getTimestamp()); + header.setServerId(ex.getEventHeader().getServerId()); + if (ex.getEventHeader() instanceof EventHeaderV4) { + header.setEventLength(((EventHeaderV4) ex.getEventHeader()).getEventLength()); + header.setNextPosition(((EventHeaderV4) ex.getEventHeader()).getNextPosition()); + header.setFlags(((EventHeaderV4) ex.getEventHeader()).getFlags()); + } + EventData data = new EventDataDeserializationExceptionData(ex); + return new Event(header, data); + } + } + }; + + eventDeserializer.setEventDataDeserializer(EventType.WRITE_ROWS, new WriteRowsEventMeshDeserializer(tableMapEventByTableId)); + eventDeserializer.setEventDataDeserializer(EventType.UPDATE_ROWS, new UpdateRowsEventMeshDeserializer(tableMapEventByTableId)); + eventDeserializer.setEventDataDeserializer(EventType.DELETE_ROWS, new DeleteRowsEventMeshDeserializer(tableMapEventByTableId)); + eventDeserializer.setEventDataDeserializer(EventType.EXT_WRITE_ROWS, + new WriteRowsEventMeshDeserializer(tableMapEventByTableId).setMayContainExtraInformation(true)); + eventDeserializer.setEventDataDeserializer(EventType.EXT_UPDATE_ROWS, + new UpdateRowsEventMeshDeserializer(tableMapEventByTableId).setMayContainExtraInformation(true)); + eventDeserializer.setEventDataDeserializer(EventType.EXT_DELETE_ROWS, + new DeleteRowsEventMeshDeserializer(tableMapEventByTableId).setMayContainExtraInformation(true)); + + // Set the event deserializer for the MySQL client + client.setEventDeserializer(eventDeserializer); + // Register an event listener for the MySQL client + client.registerEventListener((event) -> eventMeshMysqlEventListener(event, context)); + // Register a lifecycle listener for the MySQL client + client.registerLifecycleListener(new LifecycleListener() { + + @Override + public void onConnect(BinaryLogClient client) { + log.info("Client connect MySQL Server success"); + } + + @Override + public void onCommunicationFailure(BinaryLogClient client, Exception ex) { + log.error("Communicate with mysql error", ex); + } + + @Override + public void onEventDeserializationFailure(BinaryLogClient client, Exception ex) { + log.error("Event deserialization failure", ex); + } + + @Override + public void onDisconnect(BinaryLogClient client) { + log.info("Disconnect Mysql"); + } + }); + + // Register custom event handlers... + eventHandlers.put(EventType.STOP, event -> handleStopEvent(context, event)); + eventHandlers.put(EventType.HEARTBEAT, event -> handleHeartbeatEvent(context, event)); + eventHandlers.put(EventType.INCIDENT, event -> handleServerIncident(context, event)); + eventHandlers.put(EventType.ROTATE, event -> handleRotateEvent(context, event)); + eventHandlers.put(EventType.TABLE_MAP, event -> handleTableMapEvent(context, event)); + eventHandlers.put(EventType.QUERY, event -> handleQueryEvent(context, event)); + eventHandlers.put(EventType.TRANSACTION_PAYLOAD, event -> handleTransactionPayload(context, event)); + + // Used to support 5.1.16 - mysql-trunk + eventHandlers.put(EventType.WRITE_ROWS, event -> handleInsertEvent(context, event)); + eventHandlers.put(EventType.UPDATE_ROWS, event -> handleUpdateEvent(context, event)); + eventHandlers.put(EventType.DELETE_ROWS, event -> handleDeleteEvent(context, event)); + + // Used in case of RBR (5.1.18+). + eventHandlers.put(EventType.EXT_WRITE_ROWS, event -> handleInsertEvent(context, event)); + eventHandlers.put(EventType.EXT_UPDATE_ROWS, event -> handleUpdateEvent(context, event)); + eventHandlers.put(EventType.EXT_DELETE_ROWS, event -> handleDeleteEvent(context, event)); + + eventHandlers.put(EventType.VIEW_CHANGE, (event) -> handleViewChangeEvent(context, event)); + eventHandlers.put(EventType.XA_PREPARE, (event) -> handleXAPrepareTransactionEvent(context, event)); + eventHandlers.put(EventType.XID, (event) -> handleTransactionCompletionEvent(context, event)); + } + + public EventMeshGtidSet filterGtidSet(MysqlJdbcContext offsetContext, EventMeshGtidSet availableServerEventMeshGtidSet, + EventMeshGtidSet purgedServerGtid) { + String gtidStr = offsetContext.getGtidSet(); + if (gtidStr == null) { + return null; + } + + EventMeshGtidSet filteredEventMeshGtidSet = new EventMeshGtidSet(gtidStr); + + final EventMeshGtidSet knownEventMeshGtidSet = filteredEventMeshGtidSet; + final EventMeshGtidSet relevantAvailableServerEventMeshGtidSet = availableServerEventMeshGtidSet; + + EventMeshGtidSet mergedEventMeshGtidSet = relevantAvailableServerEventMeshGtidSet + .retainAll(uuid -> knownEventMeshGtidSet.forServerWithId(uuid) != null) + .with(purgedServerGtid) + .with(filteredEventMeshGtidSet); + + return mergedEventMeshGtidSet; + } + + /** + * handles events from the MySQL + * + * @param event mysql binlog event + * @param context mysql context + */ + private void eventMeshMysqlEventListener(Event event, MysqlJdbcContext context) { + + if (null == event) { + return; + } + final EventHeader eventHeader = event.getHeader(); + final EventType eventType = eventHeader.getEventType(); + /** + * @see ROTATE_EVENT + * +----------------------------------------------------+ + * | ROTATE_EVENT | + * +----------------------------------------------------+ + * | Event Header | Position Info | Filename| + * +----------------------------------------------------+ + * The rotate event is added to the binlog as last event to tell the reader what binlog to request next. + */ + if (eventType == EventType.ROTATE) { + RotateEventData rotateEventData = unwrapData(event); + context.setBinlogStartPoint(rotateEventData.getBinlogFilename(), rotateEventData.getBinlogPosition()); + } else if (eventHeader instanceof EventHeaderV4) { + EventHeaderV4 eventHeaderV4 = (EventHeaderV4) eventHeader; + context.setEventPosition(eventHeaderV4.getPosition(), eventHeaderV4.getEventLength()); + } + if (eventType == EventType.HEARTBEAT) { + return; + } + try { + eventQueue.put(event); + } catch (InterruptedException e) { + log.warn("Put event to queue error", e); + } + context.complete(); + } + + @Override + public String getThreadName() { + return "MySQL-CdcEngine"; + } + + /** + * Returns the name of the CDC Engine. + * + * @return String representing the name of the CDC Engine. + */ + @Override + public String getCdcEngineName() { + return "MySQL CDC Engine"; + } + + @Override + public void close() throws Exception { + client.disconnect(); + } + + /** + * When an object implementing interface Runnable is used to create a thread, starting the thread causes the object's + * run method to be called in that separately executing + * thread. + *

+ * The general contract of the method run is that it may take any action whatsoever. + * + * @see Thread#run() + */ + @Override + public void run() { + enableGtidHandle(); + do { + try { + client.connect(TimeUnit.SECONDS.toMillis(5)); + } catch (IOException | TimeoutException e) { + log.error("Binary log client connect to mysql server error, The connection will be retried in three seconds", e); + await(3, TimeUnit.SECONDS); + } + } while (!client.isConnected()); + + while (isRunning) { + Event event = null; + try { + event = eventQueue.poll(5, TimeUnit.SECONDS); + if (null == event) { + continue; + } + eventHandlers.getOrDefault(event.getHeader().getEventType(), ignore -> ignoreEvent(context, ignore)).accept(event); + } catch (Exception e) { + if (event != null) { + log.warn("Handle EventType={} error", event.getHeader().getEventType(), e); + } + } + } + } + + private void enableGtidHandle() { + // Query whether mysql supports GTID + if (this.connection.enableGTID()) { + eventHandlers.put(EventType.GTID, event -> handleGtidEvent(context, event)); + + // Query GtidSet from the MySQL Server + String availableServerGtid = this.connection.executedGTID(); + EventMeshGtidSet executedEventMeshGtidSet = new EventMeshGtidSet(availableServerGtid); + + // Get purged GTID + String purgedServerGtid = this.connection.purgedGTID(); + EventMeshGtidSet purgedServerEventMeshGtidSet = new EventMeshGtidSet(purgedServerGtid); + + EventMeshGtidSet filteredEventMeshGtidSet = filterGtidSet(context, executedEventMeshGtidSet, purgedServerEventMeshGtidSet); + if (null != filteredEventMeshGtidSet) { + client.setGtidSet(filteredEventMeshGtidSet.toString()); + this.context.completedGtidSet(filteredEventMeshGtidSet.toString()); + localGtidSet = new com.github.shyiko.mysql.binlog.GtidSet(filteredEventMeshGtidSet.toString()); + } else { + client.setBinlogFilename(this.context.getSourceInfo().getCurrentBinlogFileName()); + client.setBinlogPosition(this.context.getSourceInfo().getCurrentBinlogPosition()); + localGtidSet = new com.github.shyiko.mysql.binlog.GtidSet(""); + } + } else { + client.setBinlogFilename(this.context.getSourceInfo().getCurrentBinlogFileName()); + client.setBinlogPosition(this.context.getSourceInfo().getCurrentBinlogPosition()); + } + } + + /** + * Handles the STOP_EVENT + * + * @param context the MySQL context + * @param event the event to be handled + */ + protected void handleStopEvent(MysqlJdbcContext context, Event event) { + // The purpose of STOP_EVENT is to inform MySQL that the slave or replication client has reached the end of the binary log + // and no new events will be generated. When the slave receives a STOP_EVENT, it can take appropriate actions based on its needs, + // such as closing the connection to the master server or reconnecting to obtain a new binary log file. + log.debug("Replication client has reached the end of the binary log: {}", event); + } + + /** + * Handles the HEARTBEAT_EVENT + * + * @param context the MySQL context + * @param event the event to be handled + */ + protected void handleHeartbeatEvent(MysqlJdbcContext context, Event event) { + log.debug("Replication client handle {}", event.getHeader().getEventType()); + } + + /** + * Handles the INCIDENT_EVENT + * + * @param context the MySQL context + * @param event the event to be handled + */ + protected void handleServerIncident(MysqlJdbcContext context, Event event) { + + final EventData eventData = event.getData(); + if (eventData instanceof EventDataDeserializationExceptionData) { + log.error("Server incident: {}", event); + } + + } + + /** + * Handles the ROTATE_EVENT + * + * @param context the MySQL context + * @param event the event to be handled + */ + protected void handleRotateEvent(MysqlJdbcContext context, Event event) { + RotateEventData eventData = unwrapData(event); + assert eventData != null; + tableIdMap.clear(); + } + + @SuppressWarnings("unchecked") + protected T unwrapData(Event event) { + EventData eventData = event.getData(); + if (eventData instanceof EventDeserializer.EventDataWrapper) { + eventData = ((EventDeserializer.EventDataWrapper) eventData).getInternal(); + } + return (T) eventData; + } + + /** + * Handles the TABLE_MAP_EVENT Format @see TABLE_MAP_EVENT + * + * @param context the MySQL context + * @param event the event to be handled + */ + protected void handleTableMapEvent(MysqlJdbcContext context, Event event) { + TableMapEventData tableMapEventData = event.getData(); + final long tableId = tableMapEventData.getTableId(); + final String tableName = tableMapEventData.getTable(); + final String database = tableMapEventData.getDatabase(); + tableIdMap.put(tableId, new TableId(database, null, tableName)); + } + + /** + * Handles the QUERY_EVENT + * + * @param context mysql context + * @param event query event + */ + protected void handleQueryEvent(MysqlJdbcContext context, Event event) { + QueryEventData queryEventData = unwrapData(event); + final String sql = queryEventData.getSql().trim(); + log.debug("Received query event SQL:{}", sql); + if (StringUtils.equalsIgnoreCase("BEGIN", sql)) { + // start transaction + context.startTransaction(); + return; + } + + if (StringUtils.equalsIgnoreCase("COMMIT", sql)) { + context.commitTransaction(); + return; + } + + if (StringUtils.startsWithIgnoreCase("XA", sql)) { + // TODO: next version support + + return; + } + String sqlBegin = sql.substring(0, 6).toUpperCase(); + if (StringUtils.startsWithAny(sqlBegin, "INSERT", "UPDATE", "DELETE")) { + log.warn("Received DML '[SQL={}]' for processing, binlog probably contains events generated with statement", sql); + return; + } + + // set current parse database to Ddl parser + ddlParser.setCurrentDatabase(queryEventData.getDatabase()); + ddlParser.parse(sql, this::handleDdlEvent); + } + + private void handleDdlEvent(org.apache.eventmesh.connector.jdbc.event.Event event) { + if (event == null) { + return; + } + event.getJdbcConnectData().getPayload().ofSourceMateData().setSnapshot(false); + consumers.stream().forEach(consumer -> consumer.accept(event)); + } + + /** + * Handles the TRANSACTION_PAYLOAD_EVENT + *

+ * "binlog_transaction_compression" is a new feature introduced in MySQL 8.0.23, used for compressing transactions in the binary log (binlog). + * This event is a wrapper event and encloses many other events.It is mostly used for carrying compressed payloads as its content can be + * compressed, in which case, its metadata shall contain information about the compression metadata as well. + * + *

+ * + * @param context the MySQL context + * @param event the event to be handled + */ + protected void handleTransactionPayload(MysqlJdbcContext context, Event event) { + + TransactionPayloadEventData transactionPayloadEventData = event.getData(); + // unpack Event and handle + ArrayList uncompressedEvents = transactionPayloadEventData.getUncompressedEvents(); + for (Event uncompressedEvent : uncompressedEvents) { + final EventType eventType = uncompressedEvent.getHeader().getEventType(); + eventHandlers.getOrDefault(eventType, et -> ignoreEvent(context, et)).accept(uncompressedEvent); + } + } + + /** + * Handles the insert event. + * + * @param context The MySQL context. + * @param event The insert event. + */ + protected void handleInsertEvent(MysqlJdbcContext context, Event event) { + WriteRowsEventData writeRowsEventData = unwrapData(event); + log.debug("Received Write rows event, TableId={}", writeRowsEventData.getTableId()); + long tableNumber = writeRowsEventData.getTableId(); + TableId tableId = tableIdMap.get(tableNumber); + + if (!getHandledTables().contains(tableId)) { + log.warn("Write rows-Table {} is excluded", tableId); + return; + } + MysqlSourceMateData sourceMateData = buildMysqlSourceMateData(context, event, tableId); + List insertRows = writeRowsEventData.getRows(); + if (CollectionUtils.isEmpty(insertRows)) { + return; + } + List, Pair>> rows = new ArrayList<>(); + for (Serializable[] row : insertRows) { + Pair item = new Pair<>(row, writeRowsEventData.getIncludedColumns()); + rows.add(new Pair<>(null, item)); + } + handleCdcDmlData(context, sourceMateData, tableId, rows, CdcDmlType.INSERT); + } + + private MysqlSourceMateData buildMysqlSourceMateData(MysqlJdbcContext context, Event event, TableId tableId) { + MysqlSourceMateData sourceMateData = MysqlSourceMateData.newBuilder() + .name(sourceConnectorConfig.getName()) + .withTableId(tableId) + .serverId(sourceConnectorConfig.getMysqlConfig().getServerId()) + .binlogFile(context.getSourceInfo().getCurrentBinlogFileName()) + .position(((EventHeaderV4) event.getHeader()).getPosition()) + .build(); + return sourceMateData; + } + + private enum CdcDmlType { + INSERT, + UPDATE, + DELETE + } + + private GeneralDataChangeEvent buildEvent(CdcDmlType type, TableId tableId) { + switch (type) { + case UPDATE: + return new UpdateDataEvent(tableId); + case INSERT: + return new InsertDataEvent(tableId); + case DELETE: + return new DeleteDataEvent(tableId); + default: + return null; + } + } + + private void handleCdcDmlData(MysqlJdbcContext context, MysqlSourceMateData sourceMateData, TableId tableId, + List, Pair>> rows, CdcDmlType type) { + + TableSchema tableSchema = context.getCatalogTableSet().getTableSchema(tableId); + Map orderColumnMap = tableSchema.getOrderColumnMap(); + List columns = tableSchema.getColumns(); + List fields = null; + Builder builder = DataChanges.newBuilder(); + if (CollectionUtils.isNotEmpty(columns)) { + fields = columns.stream() + .map(col -> new Field(col.getDataType().getName(), col.isNotNull(), col.getName(), tableId.toString())) + .collect(Collectors.toList()); + } + int columnsSize = orderColumnMap.size(); + for (Pair, Pair> pair : rows) { + GeneralDataChangeEvent dataEvent = buildEvent(type, tableId); + Payload payload = dataEvent.getJdbcConnectData().getPayload(); + Schema schema = new Schema(); + Pair beforePair = Optional.ofNullable(pair.getLeft()).orElse(new Pair<>()); + Serializable[] beforeRows = beforePair.getLeft(); + if (null != beforeRows && beforeRows.length != 0) { + BitSet includedColumns = beforePair.getRight(); + Map beforeValues = new HashMap<>(beforeRows.length); + for (int index = 0; index < columnsSize; ++index) { + // Filter out empty fields + if (!includedColumns.get(index)) { + continue; + } + beforeValues.put(orderColumnMap.get(index + 1).getName(), beforeRows[index]); + } + builder.withBefore(beforeValues); + Field beforeField = new Field().withField(Payload.BEFORE_FIELD).withType("field").withName("payload.before").withRequired(false); + beforeField.withRequired(true).withFields(fields); + schema.add(beforeField); + } + + Pair afterPair = Optional.ofNullable(pair.getRight()).orElse(new Pair<>()); + Serializable[] afterRows = afterPair.getLeft(); + if (null != afterRows && afterRows.length != 0) { + BitSet includedColumns = afterPair.getRight(); + Map afterValues = new HashMap<>(afterRows.length); + for (int index = 0; index < columnsSize; ++index) { + // Filter out empty fields + if (!includedColumns.get(index)) { + continue; + } + afterValues.put(orderColumnMap.get(index + 1).getName(), afterRows[index]); + } + builder.withBefore(afterValues); + Field afterField = new Field().withField(Payload.AFTER_FIELD).withType("field").withName("payload.after").withRequired(false); + afterField.withRequired(true).withFields(fields); + schema.add(afterField); + } + payload.withSource(sourceMateData).withDataChanges(builder.build()); + dataEvent.getJdbcConnectData().setSchema(schema); + consumers.stream().forEach(consumer -> consumer.accept(dataEvent)); + + } + } + + /** + * Handles the update event. + * + * @param context The MySQL context. + * @param event The update event. + */ + protected void handleUpdateEvent(MysqlJdbcContext context, Event event) { + UpdateRowsEventData updateRowsEventData = unwrapData(event); + log.debug("Received Update rows event, Update table is {}", tableIdMap.get(updateRowsEventData.getTableId())); + long id = updateRowsEventData.getTableId(); + TableId tableId = tableIdMap.get(id); + if (!getHandledTables().contains(tableId)) { + log.debug("Update rows-Table {} is excluded", tableId); + return; + } + MysqlSourceMateData sourceMateData = buildMysqlSourceMateData(context, event, tableId); + List> updateRows = updateRowsEventData.getRows(); + if (CollectionUtils.isEmpty(updateRows)) { + return; + } + List, Pair>> rows = new ArrayList<>(); + for (Entry row : updateRows) { + Pair before = new Pair<>(row.getKey(), updateRowsEventData.getIncludedColumnsBeforeUpdate()); + Pair after = new Pair<>(row.getValue(), updateRowsEventData.getIncludedColumns()); + rows.add(new Pair<>(before, after)); + } + handleCdcDmlData(context, sourceMateData, tableId, rows, CdcDmlType.UPDATE); + } + + /** + * Handles the delete event. + * + * @param context The MySQL context. + * @param event The delete event. + */ + protected void handleDeleteEvent(MysqlJdbcContext context, Event event) { + DeleteRowsEventData deleteRowsEventData = unwrapData(event); + log.debug("Received Delete rows event, Delete table is {}", tableIdMap.get(deleteRowsEventData.getTableId())); + long id = deleteRowsEventData.getTableId(); + TableId tableId = tableIdMap.get(id); + + if (!getHandledTables().contains(tableId)) { + log.debug("Update rows-Table {} is excluded", tableId); + return; + } + MysqlSourceMateData sourceMateData = buildMysqlSourceMateData(context, event, tableId); + List deleteRows = deleteRowsEventData.getRows(); + if (CollectionUtils.isEmpty(deleteRows)) { + return; + } + List, Pair>> rows = new ArrayList<>(); + for (Serializable[] row : deleteRows) { + Pair item = new Pair<>(row, deleteRowsEventData.getIncludedColumns()); + rows.add(new Pair<>(item, null)); + } + handleCdcDmlData(context, sourceMateData, tableId, rows, CdcDmlType.DELETE); + } + + /** + * Handles the GTID event. + * + * @param context The MySQL context. + * @param event The GTID event. + */ + protected void handleGtidEvent(MysqlJdbcContext context, Event event) { + GtidEventData gtidEvent = unwrapData(event); + String gtid = gtidEvent.getMySqlGtid().toString(); + log.debug("Received GTID event: {}", gtid); + localGtidSet.add(gtid); + context.beginGtid(gtid); + } + + /** + * Handles the view change event. + * + * @param context The MySQL context. + * @param event The view change event. + */ + protected void handleViewChangeEvent(MysqlJdbcContext context, Event event) { + // TODO: Add support for handling view change event + } + + /** + * Handles the XA prepare transaction event. + * + * @param context The MySQL context. + * @param event The XA prepare transaction event. + */ + protected void handleXAPrepareTransactionEvent(MysqlJdbcContext context, Event event) { + // TODO: Add support for handling XA prepare transaction event + } + + /** + * Handles the transaction completion event. + * + * @param context The MySQL context. + * @param event The transaction completion event. + */ + protected void handleTransactionCompletionEvent(MysqlJdbcContext context, Event event) { + XidEventData xidEventData = unwrapData(event); + log.debug("Received XID event, Xid={}", xidEventData.getXid()); + context.commitTransaction(); + } + + /** + * Default handler that ignores events. + * + * @param context The MySQL context. + * @param event The event to be ignored. + */ + protected void ignoreEvent(MysqlJdbcContext context, Event event) { + log.debug("Ignoring event due to missing handler: {}", event); + } + + @Override + public void registerCdcEventConsumer(EventConsumer consumer) { + if (consumer == null) { + return; + } + consumers.add(consumer); + } + + @Override + protected Set defaultExcludeDatabase() { + return MysqlConstants.DEFAULT_EXCLUDE_DATABASE; + } + + @Override + protected MysqlAntlr4DdlParser getDdlParser() { + return ddlParser; + } + + @Override + public void setContext(MysqlJdbcContext context) { + if (context == null) { + context = MysqlJdbcContext.initialize(this.jdbcSourceConfig); + } + this.context = context; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/mysql/MysqlCdcEngineFactory.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/mysql/MysqlCdcEngineFactory.java new file mode 100644 index 0000000000..60c3c7b7c1 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/mysql/MysqlCdcEngineFactory.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.connector.jdbc.source.dialect.cdc.mysql; + +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.AbstractCdcEngineFactory; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.CdcEngine; +import org.apache.eventmesh.connector.jdbc.source.dialect.cdc.CdcEngineFactory; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlDatabaseDialect; +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import org.apache.commons.lang3.StringUtils; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MysqlCdcEngineFactory extends AbstractCdcEngineFactory implements CdcEngineFactory { + + @Override + public boolean acceptJdbcProtocol(String url) { + if (StringUtils.isBlank(url)) { + return true; + } + return url.toLowerCase().startsWith("jdbc:mysql"); + } + + /** + * Creates a CDC engine based on the provided source configuration and database dialect. + * + * @param config the source configuration for the CDC engine + * @param databaseDialect the database dialect for the CDC engine + * @return the created CDC engine + */ + @Override + public CdcEngine createCdcEngine(SourceConfig config, DatabaseDialect databaseDialect) { + return new MysqlCdcEngine(config, (MysqlDatabaseDialect) databaseDialect); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/mysql/RowDeserializers.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/mysql/RowDeserializers.java new file mode 100644 index 0000000000..f605e95bde --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/cdc/mysql/RowDeserializers.java @@ -0,0 +1,451 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.source.dialect.cdc.mysql; + +import java.io.IOException; +import java.io.Serializable; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Year; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Map; + +import com.github.shyiko.mysql.binlog.event.TableMapEventData; +import com.github.shyiko.mysql.binlog.event.deserialization.DeleteRowsEventDataDeserializer; +import com.github.shyiko.mysql.binlog.event.deserialization.UpdateRowsEventDataDeserializer; +import com.github.shyiko.mysql.binlog.event.deserialization.WriteRowsEventDataDeserializer; +import com.github.shyiko.mysql.binlog.io.ByteArrayInputStream; + +import lombok.extern.slf4j.Slf4j; + +/** + * Custom deserializers for the MySQL Binlog Client.MySQL Binlog Client row deserializers convert MySQL raw row data into {@link java.sql.Date}, + * {@link java.sql.Time}, and {@link java.sql.Timestamp} values using {@link java.util.Calendar} instances. EventMesh convert the raw MySQL row values + * directly into {@link LocalDate}, {@link LocalTime}, {@link LocalDateTime}, and {@link java.time.OffsetDateTime}. + */ +@Slf4j +public class RowDeserializers { + + public static class WriteRowsEventMeshDeserializer extends WriteRowsEventDataDeserializer { + + public WriteRowsEventMeshDeserializer(Map tableMapEventByTableId) { + super(tableMapEventByTableId); + } + + @Override + protected Serializable deserializeString(int length, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeString(length, inputStream); + } + + @Override + protected Serializable deserializeVarString(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeVarString(meta, inputStream); + } + + @Override + protected Serializable deserializeDate(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeDate(inputStream); + } + + @Override + protected Serializable deserializeDatetime(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeDatetime(inputStream); + } + + @Override + protected Serializable deserializeDatetimeV2(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeDatetimeV2(meta, inputStream); + } + + @Override + protected Serializable deserializeTimeV2(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTimeV2(meta, inputStream); + } + + @Override + protected Serializable deserializeTime(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTime(inputStream); + } + + @Override + protected Serializable deserializeTimestamp(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTimestamp(inputStream); + } + + @Override + protected Serializable deserializeTimestampV2(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTimestampV2(meta, inputStream); + } + + @Override + protected Serializable deserializeYear(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeYear(inputStream); + } + } + + public static class UpdateRowsEventMeshDeserializer extends UpdateRowsEventDataDeserializer { + + public UpdateRowsEventMeshDeserializer(Map tableMapEventByTableId) { + super(tableMapEventByTableId); + } + + @Override + protected Serializable deserializeString(int length, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeString(length, inputStream); + } + + @Override + protected Serializable deserializeVarString(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeVarString(meta, inputStream); + } + + @Override + protected Serializable deserializeDate(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeDate(inputStream); + } + + @Override + protected Serializable deserializeDatetime(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeDatetime(inputStream); + } + + @Override + protected Serializable deserializeDatetimeV2(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeDatetimeV2(meta, inputStream); + } + + @Override + protected Serializable deserializeTimeV2(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTimeV2(meta, inputStream); + } + + @Override + protected Serializable deserializeTime(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTime(inputStream); + } + + @Override + protected Serializable deserializeTimestamp(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTimestamp(inputStream); + } + + @Override + protected Serializable deserializeTimestampV2(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTimestampV2(meta, inputStream); + } + + @Override + protected Serializable deserializeYear(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeYear(inputStream); + } + } + + public static class DeleteRowsEventMeshDeserializer extends DeleteRowsEventDataDeserializer { + + public DeleteRowsEventMeshDeserializer(Map tableMapEventByTableId) { + super(tableMapEventByTableId); + } + + @Override + protected Serializable deserializeString(int length, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeString(length, inputStream); + } + + @Override + protected Serializable deserializeVarString(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeVarString(meta, inputStream); + } + + @Override + protected Serializable deserializeDate(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeDate(inputStream); + } + + @Override + protected Serializable deserializeDatetime(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeDatetime(inputStream); + } + + @Override + protected Serializable deserializeDatetimeV2(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeDatetimeV2(meta, inputStream); + } + + @Override + protected Serializable deserializeTimeV2(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTimeV2(meta, inputStream); + } + + @Override + protected Serializable deserializeTime(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTime(inputStream); + } + + @Override + protected Serializable deserializeTimestamp(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTimestamp(inputStream); + } + + @Override + protected Serializable deserializeTimestampV2(int meta, ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeTimestampV2(meta, inputStream); + } + + @Override + protected Serializable deserializeYear(ByteArrayInputStream inputStream) throws IOException { + return RowDeserializers.deserializeYear(inputStream); + } + } + + protected static Serializable deserializeTimestamp(ByteArrayInputStream inputStream) throws IOException { + long epochSecond = inputStream.readLong(4); + int nanoSeconds = 0; // no fractional seconds + return ZonedDateTime.ofInstant(Instant.ofEpochSecond(epochSecond, nanoSeconds), ZoneOffset.UTC); + } + + protected static Serializable deserializeTimestampV2(int meta, ByteArrayInputStream inputStream) throws IOException { + long epochSecond = bigEndianLong(inputStream.read(4), 0, 4); + int nanoSeconds = deserializeFractionalSecondsInNanos(meta, inputStream); + return ZonedDateTime.ofInstant(Instant.ofEpochSecond(epochSecond, nanoSeconds), ZoneOffset.UTC); + } + + protected static Serializable deserializeYear(ByteArrayInputStream inputStream) throws IOException { + return Year.of(1900 + inputStream.readInteger(1)); + } + + /** + * Deserializes a string from the given input stream. Since the charset is not present in the binary log, it is impossible to distinguish between + * CHAR and BINARY types. Therefore, the method returns a byte array instead of a String. + * + * @param length The length of the string. + * @param inputStream The input stream from which to read the string. + * @return A byte array representing the deserialized string. + * @throws IOException If an I/O error occurs while reading the input stream. + */ + private static Serializable deserializeString(int length, ByteArrayInputStream inputStream) throws IOException { + // charset is not present in the binary log (meaning there is no way to distinguish between CHAR / BINARY) + // as a result - return byte[] instead of an actual String + int stringLength = length < 256 ? inputStream.readInteger(1) : inputStream.readInteger(2); + return inputStream.read(stringLength); + } + + private static Serializable deserializeVarString(int meta, ByteArrayInputStream inputStream) throws IOException { + int varcharLength = meta < 256 ? inputStream.readInteger(1) : inputStream.readInteger(2); + return inputStream.read(varcharLength); + } + + private static Serializable deserializeDate(ByteArrayInputStream inputStream) throws IOException { + int value = inputStream.readInteger(3); + int day = value % 32; + value >>>= 5; + int month = value % 16; + int year = value >> 4; + // https://dev.mysql.com/doc/refman/8.0/en/datetime.html + if (year == 0 || month == 0 || day == 0) { + return null; + } + return LocalDate.of(year, month, day); + } + + protected static Serializable deserializeDatetime(ByteArrayInputStream inputStream) throws IOException { + int[] split = split(inputStream.readLong(8), 100, 6); + int year = split[5]; + int month = split[4]; // 1-based month number + int day = split[3]; // 1-based day of the month + int hours = split[2]; + int minutes = split[1]; + int seconds = split[0]; + int nanoOfSecond = 0; // This version does not support fractional seconds + if (year == 0 || month == 0 || day == 0) { + return null; + } + return LocalDateTime.of(year, month, day, hours, minutes, seconds, nanoOfSecond); + } + + private static final int MASK_10_BITS = (1 << 10) - 1; + private static final int MASK_6_BITS = (1 << 6) - 1; + + protected static Serializable deserializeTimeV2(int meta, ByteArrayInputStream inputStream) throws IOException { + + /** + * Binary Format for TIME in MySQL binlog: + * TIME + * +------+---------------+----------------------------------------------------+ + * | Bits | Field | Value Range | + * +------+---------------+----------------------------------------------------+ + * | 1 | sign | (Used for sign, when on disk) | + * | 1 | unused | (Reserved for wider hour range, e.g. for intervals)| + * | 10 | hour | (0-838) | + * | 6 | minute | (0-59) | + * | 6 | second | (0-59) | + * | 24 | microseconds | (0-999999) | + * +------+---------------+----------------------------------------------------+ + * + * + fractional-seconds storage (size depends on meta) + */ + long time = bigEndianLong(inputStream.read(3), 0, 3); + boolean isNegative = bitSlice(time, 0, 1, 24) == 0; + int hours = bitSlice(time, 2, 10, 24); + int minutes = bitSlice(time, 12, 6, 24); + int seconds = bitSlice(time, 18, 6, 24); + int nanoSeconds; + if (isNegative) { // mysql binary arithmetic for negative encoded values + hours = ~hours & MASK_10_BITS; + hours = hours & ~(1 << 10); // unset sign bit + minutes = ~minutes & MASK_6_BITS; + minutes = minutes & ~(1 << 6); // unset sign bit + seconds = ~seconds & MASK_6_BITS; + seconds = seconds & ~(1 << 6); // unset sign bit + nanoSeconds = deserializeFractionalSecondsInNanosNegative(meta, inputStream); + if (nanoSeconds == 0 && seconds < 59) { // weird java Duration behavior + ++seconds; + } + hours = -hours; + minutes = -minutes; + seconds = -seconds; + nanoSeconds = -nanoSeconds; + } else { + nanoSeconds = deserializeFractionalSecondsInNanos(meta, inputStream); + } + + return LocalTime.of(hours, minutes, seconds, nanoSeconds); + } + + protected static Serializable deserializeTime(ByteArrayInputStream inputStream) throws IOException { + // Times are stored as an integer as `HHMMSS`, so we need to split out the digits ... + int value = inputStream.readInteger(3); + int[] split = split(value, 100, 3); + int hours = split[2]; + int minutes = split[1]; + int seconds = split[0]; + return LocalTime.of(hours, minutes, seconds); + } + + protected static int deserializeFractionalSecondsInNanosNegative(int fsp, ByteArrayInputStream inputStream) throws IOException { + // Calculate the number of bytes to read, which is + // '1' when fsp=(1,2) + // '2' when fsp=(3,4) and + // '3' when fsp=(5,6) + int length = (fsp + 1) / 2; + if (length > 0) { + long fraction = bigEndianLong(inputStream.read(length), 0, length); + int maskBits = 0; + switch (length) { // mask bits according to field precision + case 1: + maskBits = 8; + break; + case 2: + maskBits = 15; + break; + case 3: + maskBits = 20; + break; + default: + break; + } + fraction = ~fraction & ((1 << maskBits) - 1); + fraction = (fraction & ~(1 << maskBits)) + 1; // unset sign bit + // Convert the fractional value (which has extra trailing digit for fsp=1,3, and 5) to nanoseconds ... + return (int) (fraction / (0.0000001 * Math.pow(100, length - 1))); + } + return 0; + } + + private static int bigEndianInteger(byte[] bytes, int offset, int length) { + int result = 0; + for (int i = offset; i < (offset + length); i++) { + byte b = bytes[i]; + result = (result << 8) | (b >= 0 ? (int) b : (b + 256)); + } + return result; + } + + protected static Serializable deserializeDatetimeV2(int meta, ByteArrayInputStream inputStream) + throws IOException { + + /** + * DATETIME + * 1 sign (used when on disk) + * 17 year*13+month (year 0-9999, month 0-12) + * 5 day (0-31) + * 5 hour (0-23) + * 6 minute (0-59) + * 6 second (0-59) + * 24 microseconds (0-999999) + * + * (5 bytes in total) + * + * + fractional-seconds storage (size depends on meta) + */ + long datetime = bigEndianLong(inputStream.read(5), 0, 5); + int yearMonth = bitSlice(datetime, 1, 17, 40); + int year = yearMonth / 13; + int month = yearMonth % 13; // 1-based month number + int day = bitSlice(datetime, 18, 5, 40); // 1-based day of the month + int hours = bitSlice(datetime, 23, 5, 40); + int minutes = bitSlice(datetime, 28, 6, 40); + int seconds = bitSlice(datetime, 34, 6, 40); + int nanoOfSecond = deserializeFractionalSecondsInNanos(meta, inputStream); + if (year == 0 || month == 0 || day == 0) { + return null; + } + return LocalDateTime.of(year, month, day, hours, minutes, seconds, nanoOfSecond); + } + + private static int[] split(long value, int divider, int length) { + int[] result = new int[length]; + for (int i = 0; i < length - 1; i++) { + result[i] = (int) (value % divider); + value /= divider; + } + result[length - 1] = (int) value; + return result; + } + + protected static long bigEndianLong(byte[] bytes, int offset, int length) { + long result = 0; + for (int i = offset; i < (offset + length); i++) { + byte b = bytes[i]; + result = (result << 8) | (b >= 0 ? (int) b : (b + 256)); + } + return result; + } + + protected static int bitSlice(long value, int bitOffset, int numberOfBits, int payloadSize) { + long result = value >> payloadSize - (bitOffset + numberOfBits); + return (int) (result & ((1 << numberOfBits) - 1)); + } + + protected static int deserializeFractionalSecondsInNanos(int fsp, ByteArrayInputStream inputStream) throws IOException { + // Calculate the number of bytes to read, which is + // '1' when fsp=(1,2) -- 7 + // '2' when fsp=(3,4) and -- 12 + // '3' when fsp=(5,6) -- 21 + int length = (fsp + 1) / 2; + if (length > 0) { + long fraction = bigEndianLong(inputStream.read(length), 0, length); + // Convert the fractional value (which has extra trailing digit for fsp=1,3, and 5) to nanoseconds ... + return (int) (fraction / (0.0000001 * Math.pow(100, length - 1))); + } + return 0; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/EventDataDeserializationExceptionData.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/EventDataDeserializationExceptionData.java new file mode 100644 index 0000000000..4d06b6cc21 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/EventDataDeserializationExceptionData.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.connector.jdbc.source.dialect.mysql; + +import com.github.shyiko.mysql.binlog.event.EventData; +import com.github.shyiko.mysql.binlog.event.deserialization.EventDataDeserializationException; + +public class EventDataDeserializationExceptionData implements EventData { + + private static final long serialVersionUID = 7990993358724828999L; + + private final EventDataDeserializationException cause; + + public EventDataDeserializationExceptionData(EventDataDeserializationException cause) { + this.cause = cause; + } + + public EventDataDeserializationException getCause() { + return cause; + } + + @Override + public String toString() { + return "EventDataDeserializationExceptionData [cause=" + cause + "]"; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/EventMeshGtidSet.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/EventMeshGtidSet.java new file mode 100644 index 0000000000..0b2aca1c77 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/EventMeshGtidSet.java @@ -0,0 +1,483 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.jdbc.source.dialect.mysql; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public final class EventMeshGtidSet { + + private final Map uuidSetsByServerId = new TreeMap<>(); // sorts on keys + public static Pattern GTID_DELIMITER = Pattern.compile(":"); + + protected EventMeshGtidSet(Map uuidSetsByServerId) { + this.uuidSetsByServerId.putAll(uuidSetsByServerId); + } + + /** + * @param gtids the string representation of the GTIDs. + */ + public EventMeshGtidSet(String gtids) { + new com.github.shyiko.mysql.binlog.GtidSet(gtids).getUUIDSets().forEach(uuidSet -> { + uuidSetsByServerId.put(uuidSet.getServerId().toString(), new UUIDSet(uuidSet)); + }); + StringBuilder sb = new StringBuilder(); + uuidSetsByServerId.values().forEach(uuidSet -> { + if (sb.length() != 0) { + sb.append(','); + } + sb.append(uuidSet.toString()); + }); + } + + /** + * Obtain a copy of this {@link EventMeshGtidSet} except with only the GTID ranges that have server UUIDs that match the given predicate. + * + * @param sourceFilter the predicate that returns whether a server UUID is to be included + * @return the new GtidSet, or this object if {@code sourceFilter} is null; never null + */ + public EventMeshGtidSet retainAll(Predicate sourceFilter) { + if (sourceFilter == null) { + return this; + } + Map newSets = this.uuidSetsByServerId.entrySet() + .stream() + .filter(entry -> sourceFilter.test(entry.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + return new EventMeshGtidSet(newSets); + } + + /** + * Get an immutable collection of the {@link UUIDSet range of GTIDs for a single server}. + * + * @return the {@link UUIDSet GTID ranges for each server}; never null + */ + public Collection getUUIDSets() { + return Collections.unmodifiableCollection(uuidSetsByServerId.values()); + } + + /** + * Find the {@link UUIDSet} for the server with the specified Uuid. + * + * @param uuid the Uuid of the server + * @return the {@link UUIDSet} for the identified server, or {@code null} if there are no GTIDs from that server. + */ + public UUIDSet forServerWithId(String uuid) { + return uuidSetsByServerId.get(uuid); + } + + /** + * Determine if the GTIDs represented by this object are contained completely within the supplied set of GTIDs. + * + * @param other the other set of GTIDs; may be null + * @return {@code true} if all of the GTIDs in this set are completely contained within the supplied set of GTIDs, or {@code false} otherwise + */ + public boolean isContainedWithin(EventMeshGtidSet other) { + if (other == null) { + return false; + } + if (this.equals(other)) { + return true; + } + for (UUIDSet uuidSet : uuidSetsByServerId.values()) { + UUIDSet thatSet = other.forServerWithId(uuidSet.getUUID()); + if (!uuidSet.isContainedWithin(thatSet)) { + return false; + } + } + return true; + } + + /** + * Obtain a copy of this {@link EventMeshGtidSet} except overwritten with all of the GTID ranges in the supplied {@link EventMeshGtidSet}. + * + * @param other the other {@link EventMeshGtidSet} with ranges to add/overwrite on top of those in this set; + * @return the new GtidSet, or this object if {@code other} is null or empty; never null + */ + public EventMeshGtidSet with(EventMeshGtidSet other) { + if (other == null || other.uuidSetsByServerId.isEmpty()) { + return this; + } + Map newSet = new HashMap<>(); + newSet.putAll(this.uuidSetsByServerId); + newSet.putAll(other.uuidSetsByServerId); + return new EventMeshGtidSet(newSet); + } + + /** + * Retrieves the beginning GTID set. + * + * @return The starting state of the GTID set. + */ + public EventMeshGtidSet getGtidSetBeginning() { + // Create a new map to store the GTID set + Map newSet = new HashMap<>(); + + // Iterate over each UUID set for each server ID + for (UUIDSet uuidSet : uuidSetsByServerId.values()) { + // Store the beginning state of each UUID set as the value in the new set, with UUID as the key + newSet.put(uuidSet.getUUID(), uuidSet.asIntervalBeginning()); + } + + // Create and return a new GTID set object using the new map + return new EventMeshGtidSet(newSet); + } + + public boolean contains(String gtid) { + String[] split = GTID_DELIMITER.split(gtid); + String sourceId = split[0]; + UUIDSet uuidSet = forServerWithId(sourceId); + if (uuidSet == null) { + return false; + } + long transactionId = Long.parseLong(split[1]); + return uuidSet.contains(transactionId); + } + + public EventMeshGtidSet subtract(EventMeshGtidSet other) { + if (other == null) { + return this; + } + Map newSets = this.uuidSetsByServerId.entrySet() + .stream() + .filter(entry -> !entry.getValue().isContainedWithin(other.forServerWithId(entry.getKey()))) + .map(entry -> new AbstractMap.SimpleEntry<>(entry.getKey(), entry.getValue().subtract(other.forServerWithId(entry.getKey())))) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + return new EventMeshGtidSet(newSets); + } + + @Override + public int hashCode() { + return uuidSetsByServerId.keySet().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof EventMeshGtidSet) { + EventMeshGtidSet that = (EventMeshGtidSet) obj; + return this.uuidSetsByServerId.equals(that.uuidSetsByServerId); + } + return false; + } + + @Override + public String toString() { + List gtids = new ArrayList(); + for (UUIDSet uuidSet : uuidSetsByServerId.values()) { + gtids.add(uuidSet.toString()); + } + return String.join(",", gtids); + } + + /** + * A range of GTIDs for a single server with a specific Uuid. + */ + + public static class UUIDSet { + + private final String uuid; + private final LinkedList intervals = new LinkedList<>(); + + protected UUIDSet(com.github.shyiko.mysql.binlog.GtidSet.UUIDSet uuidSet) { + this.uuid = uuidSet.getServerId().toString(); + uuidSet.getIntervals().forEach(interval -> { + intervals.add(new Interval(interval.getStart(), interval.getEnd())); + }); + Collections.sort(this.intervals); + if (this.intervals.size() > 1) { + // Collapse adjacent intervals ... + for (int i = intervals.size() - 1; i != 0; --i) { + Interval before = this.intervals.get(i - 1); + Interval after = this.intervals.get(i); + if ((before.getEnd() + 1) == after.getStart()) { + this.intervals.set(i - 1, new Interval(before.getStart(), after.getEnd())); + this.intervals.remove(i); + } + } + } + } + + protected UUIDSet(String uuid, Interval interval) { + this.uuid = uuid; + this.intervals.add(interval); + } + + protected UUIDSet(String uuid, List intervals) { + this.uuid = uuid; + this.intervals.addAll(intervals); + } + + public UUIDSet asIntervalBeginning() { + Interval start = new Interval(intervals.get(0).getStart(), intervals.get(0).getStart()); + return new UUIDSet(this.uuid, start); + } + + /** + * Get the Uuid for the server that generated the GTIDs. + * + * @return the server's Uuid; never null + */ + public String getUUID() { + return uuid; + } + + /** + * Get the intervals of transaction numbers. + * + * @return the immutable transaction intervals; never null + */ + public List getIntervals() { + return Collections.unmodifiableList(intervals); + } + + /** + * Determine if the set of transaction numbers from this server is completely within the set of transaction numbers from the set of + * transaction numbers in the supplied set. + * + * @param other the set to compare with this set + * @return {@code true} if this server's transaction numbers are a subset of the transaction numbers of the supplied set, or false otherwise + */ + public boolean isContainedWithin(UUIDSet other) { + if (other == null) { + return false; + } + if (!this.getUUID().equalsIgnoreCase(other.getUUID())) { + // Not even the same server ... + return false; + } + if (this.intervals.isEmpty()) { + return true; + } + if (other.intervals.isEmpty()) { + return false; + } + assert this.intervals.size() > 0; + assert other.intervals.size() > 0; + + // Every interval in this must be within an interval of the other ... + for (Interval thisInterval : this.intervals) { + boolean found = false; + for (Interval otherInterval : other.intervals) { + if (thisInterval.isContainedWithin(otherInterval)) { + found = true; + break; + } + } + if (!found) { + return false; // didn't find a match + } + } + return true; + } + + public boolean contains(long transactionId) { + for (Interval interval : this.intervals) { + if (interval.contains(transactionId)) { + return true; + } + } + return false; + } + + @Override + public int hashCode() { + return uuid.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj instanceof UUIDSet) { + UUIDSet that = (UUIDSet) obj; + return this.getUUID().equalsIgnoreCase(that.getUUID()) && this.getIntervals().equals(that.getIntervals()); + } + return super.equals(obj); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(uuid).append(':'); + Iterator iter = intervals.iterator(); + if (iter.hasNext()) { + sb.append(iter.next()); + } + while (iter.hasNext()) { + sb.append(':'); + sb.append(iter.next()); + } + return sb.toString(); + } + + public UUIDSet subtract(UUIDSet other) { + if (!uuid.equals(other.getUUID())) { + throw new IllegalArgumentException("UUIDSet subtraction is supported only within a single server UUID"); + } + List result = new ArrayList<>(); + for (Interval interval : intervals) { + result.addAll(interval.removeAll(other.getIntervals())); + } + return new UUIDSet(uuid, result); + } + } + + public static class Interval implements Comparable { + + private final long start; + private final long end; + + public Interval(long start, long end) { + this.start = start; + this.end = end; + } + + /** + * Get the starting transaction number in this interval. + * + * @return this interval's first transaction number + */ + public long getStart() { + return start; + } + + /** + * Get the ending transaction number in this interval. + * + * @return this interval's last transaction number + */ + public long getEnd() { + return end; + } + + /** + * Determine if this interval is completely within the supplied interval. + * + * @param other the interval to compare with + * @return {@code true} if the {@link #getStart() start} is greater than or equal to the supplied interval's {@link #getStart() start} and the + * {@link #getEnd() end} is less than or equal to the supplied interval's {@link #getEnd() end}, or {@code false} otherwise + */ + public boolean isContainedWithin(Interval other) { + if (other == this) { + return true; + } + if (other == null) { + return false; + } + return this.getStart() >= other.getStart() && this.getEnd() <= other.getEnd(); + } + + public boolean contains(long transactionId) { + return getStart() <= transactionId && transactionId <= getEnd(); + } + + public boolean contains(Interval other) { + return getStart() <= other.getStart() && getEnd() >= other.getEnd(); + } + + public boolean nonintersecting(Interval other) { + return other.getEnd() < this.getStart() || other.getStart() > this.getEnd(); + } + + public List remove(Interval other) { + if (nonintersecting(other)) { + return Collections.singletonList(this); + } + if (other.contains(this)) { + return Collections.emptyList(); + } + List result = new LinkedList<>(); + if (this.getStart() < other.getStart()) { + Interval part = new Interval(this.getStart(), other.getStart() - 1); + result.add(part); + } + if (other.getEnd() < this.getEnd()) { + Interval part = new Interval(other.getEnd() + 1, this.getEnd()); + result.add(part); + } + return result; + } + + public List removeAll(List otherIntervals) { + List thisIntervals = new LinkedList<>(); + thisIntervals.add(this); + List result = new LinkedList<>(); + result.add(this); + for (Interval other : otherIntervals) { + result = new LinkedList<>(); + for (Interval thisInterval : thisIntervals) { + result.addAll(thisInterval.remove(other)); + } + thisIntervals = result; + } + return result; + } + + @Override + public int compareTo(Interval that) { + if (that == this) { + return 0; + } + long diff = this.start - that.start; + if (diff > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + if (diff < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } + return (int) diff; + } + + @Override + public int hashCode() { + return (int) getStart(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof Interval) { + Interval that = (Interval) obj; + return this.getStart() == that.getStart() && this.getEnd() == that.getEnd(); + } + return false; + } + + @Override + public String toString() { + return "" + getStart() + "-" + getEnd(); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlConstants.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlConstants.java new file mode 100644 index 0000000000..44f10cee6c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlConstants.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.connector.jdbc.source.dialect.mysql; + +import java.util.HashSet; +import java.util.Set; + +public final class MysqlConstants { + + public static final Set DEFAULT_EXCLUDE_DATABASE = new HashSet<>(); + + static { + DEFAULT_EXCLUDE_DATABASE.add("information_schema"); + DEFAULT_EXCLUDE_DATABASE.add("mysql"); + DEFAULT_EXCLUDE_DATABASE.add("performance_schema"); + DEFAULT_EXCLUDE_DATABASE.add("sys"); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDataTypeConvertor.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDataTypeConvertor.java new file mode 100644 index 0000000000..33b26ebe72 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDataTypeConvertor.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.connector.jdbc.source.dialect.mysql; + +import org.apache.eventmesh.connector.jdbc.DataTypeConvertor; +import org.apache.eventmesh.connector.jdbc.exception.DataTypeConvertException; +import org.apache.eventmesh.connector.jdbc.table.type.CalendarType; +import org.apache.eventmesh.connector.jdbc.table.type.DecimalType; +import org.apache.eventmesh.connector.jdbc.table.type.EventMeshDataType; +import org.apache.eventmesh.connector.jdbc.table.type.PrimitiveByteArrayType; +import org.apache.eventmesh.connector.jdbc.table.type.PrimitiveType; +import org.apache.eventmesh.connector.jdbc.table.type.SQLType; + +import java.sql.JDBCType; +import java.util.Map; +import java.util.Objects; + +import com.mysql.cj.MysqlType; + +public class MysqlDataTypeConvertor implements DataTypeConvertor { + + public static final String PRECISION = "precision"; + + public static final String SCALE = "scale"; + + /** + * @see Fixed-Point Types (Exact Value) - DECIMAL, NUMERIC + */ + public static final Integer DEFAULT_PRECISION = 10; + + public static final Integer DEFAULT_SCALE = 0; + + /** + * Converts a string representation of a connector data type to the corresponding JDBCType. + * + * @param connectorDataType The string representation of the connector data type. + * @return The corresponding JDBCType, or null if the connector data type is not recognized. + */ + @Override + public JDBCType toJDBCType(String connectorDataType) { + MysqlType mysqlType = MysqlType.getByName(connectorDataType); + return JDBCType.valueOf(mysqlType.getJdbcType()); + } + + /** + * Converts a connector data type to an EventMesh data type. e.g. "int", "varchar(255)","decimal(10,2)" + * + * @param connectorDataType The connector data type to be converted. + * @return The converted EventMesh data type. + * @throws DataTypeConvertException If the conversion fails. + */ + @Override + public EventMeshDataType toEventMeshType(String connectorDataType) throws DataTypeConvertException { + MysqlType mysqlType = MysqlType.getByName(connectorDataType); + return toEventMeshType(mysqlType, null); + } + + /** + * Converts JDBCType and dataTypeProperties to EventMeshDataType. + * + * @param jdbcType the JDBCType to be converted + * @param dataTypeProperties the properties of the data type + * @return the converted EventMeshDataType + * @throws DataTypeConvertException if there is an error during conversion + */ + @Override + public EventMeshDataType toEventMeshType(JDBCType jdbcType, Map dataTypeProperties) throws DataTypeConvertException { + return toEventMeshType(MysqlType.getByJdbcType(jdbcType.getVendorTypeNumber()), dataTypeProperties); + } + + /** + * Converts a connector data type to an EventMesh data type with additional data type properties. + * + * @param connectorDataType The connector data type to be converted. + * @param dataTypeProperties Additional data type properties. + * @return The converted EventMesh data type. + * @throws DataTypeConvertException If the conversion fails. + */ + @Override + public EventMeshDataType toEventMeshType(MysqlType connectorDataType, Map dataTypeProperties) throws DataTypeConvertException { + + Objects.requireNonNull(connectorDataType, "MysqlType can't be null"); + + switch (connectorDataType) { + case NULL: + return PrimitiveType.VOID_TYPE; + case BOOLEAN: + return PrimitiveType.BOOLEAN_TYPE; + case BIT: { + /** + * @see Mysql doc + */ + if (null == dataTypeProperties) { + return PrimitiveByteArrayType.BYTES_TYPE; + } + Integer precision = (Integer) dataTypeProperties.get(MysqlDataTypeConvertor.PRECISION); + if (precision != null && precision == 1) { + return PrimitiveType.BOOLEAN_TYPE; + } + return PrimitiveByteArrayType.BYTES_TYPE; + } + case TINYINT: + return PrimitiveType.BYTE_TYPE; + case TINYINT_UNSIGNED: + case SMALLINT: + return PrimitiveType.SHORT_TYPE; + case SMALLINT_UNSIGNED: + case INT: + case MEDIUMINT: + case MEDIUMINT_UNSIGNED: + return PrimitiveType.INT_TYPE; + case INT_UNSIGNED: + case BIGINT: + return PrimitiveType.LONG_TYPE; + case FLOAT: + case FLOAT_UNSIGNED: + return PrimitiveType.FLOAT_TYPE; + case DOUBLE: + case DOUBLE_UNSIGNED: + return PrimitiveType.DOUBLE_TYPE; + case TIME: + return CalendarType.LOCAL_TIME_TYPE; + case YEAR: + case DATE: + return CalendarType.LOCAL_DATE_TYPE; + case TIMESTAMP: + case DATETIME: + return CalendarType.LOCAL_DATE_TIME_TYPE; + case CHAR: + case VARCHAR: + case TINYTEXT: + case TEXT: + case MEDIUMTEXT: + case LONGTEXT: + case JSON: + case ENUM: + return PrimitiveType.STRING_TYPE; + case BINARY: + case VARBINARY: + case TINYBLOB: + case BLOB: + case MEDIUMBLOB: + case LONGBLOB: + case GEOMETRY: + return PrimitiveByteArrayType.BYTES_TYPE; + case BIGINT_UNSIGNED: + case DECIMAL: + case DECIMAL_UNSIGNED: { + /** + * @see Mysql doc-DECIMAL, NUMERIC + */ + if (dataTypeProperties == null) { + return new DecimalType(DEFAULT_PRECISION, DEFAULT_SCALE); + } + Integer precision = (Integer) dataTypeProperties.getOrDefault(PRECISION, DEFAULT_PRECISION); + Integer scale = (Integer) dataTypeProperties.getOrDefault(SCALE, DEFAULT_SCALE); + return new DecimalType(precision, scale); + } + default: + throw new DataTypeConvertException(String.format("%s type is not supported", connectorDataType.getName())); + } + } + + /** + * Converts an EventMesh data type to a connector data type with additional data type properties. + * + * @param eventMeshDataType The EventMesh data type to be converted. + * @param dataTypeProperties Additional data type properties. + * @return The converted connector data type. + * @throws DataTypeConvertException If the conversion fails. + */ + @Override + public MysqlType toConnectorType(EventMeshDataType eventMeshDataType, Map dataTypeProperties) throws DataTypeConvertException { + + Objects.requireNonNull(eventMeshDataType, "Parameter eventMeshDataType can not be null"); + SQLType sqlType = eventMeshDataType.getSQLType(); + + switch (sqlType) { + case BOOLEAN: + return MysqlType.BOOLEAN; + case TINYINT: + return MysqlType.TINYINT; + case SMALLINT: + return MysqlType.SMALLINT; + case INTEGER: + return MysqlType.INT; + case BIGINT: + return MysqlType.BIGINT; + case FLOAT: + return MysqlType.FLOAT; + case DOUBLE: + return MysqlType.DOUBLE; + case DECIMAL: + return MysqlType.DECIMAL; + case NULL: + return MysqlType.NULL; + case BINARY: + return MysqlType.BIT; + case DATE: + return MysqlType.DATE; + case TIME: + return MysqlType.DATETIME; + case TIMESTAMP: + return MysqlType.TIMESTAMP; + case ARRAY: + case MAP: + case ROW: + case STRING: + return MysqlType.VARCHAR; + default: + throw new DataTypeConvertException(String.format("%s type is not supported", sqlType.name())); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDatabaseDialect.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDatabaseDialect.java new file mode 100644 index 0000000000..bfd6a73006 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDatabaseDialect.java @@ -0,0 +1,305 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.source.dialect.mysql; + +import org.apache.eventmesh.connector.jdbc.DataTypeConvertor; +import org.apache.eventmesh.connector.jdbc.JdbcDriverMetaData; +import org.apache.eventmesh.connector.jdbc.connection.mysql.MysqlJdbcConnection; +import org.apache.eventmesh.connector.jdbc.exception.CatalogException; +import org.apache.eventmesh.connector.jdbc.exception.DatabaseNotExistException; +import org.apache.eventmesh.connector.jdbc.exception.TableNotExistException; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.AbstractGeneralDatabaseDialect; +import org.apache.eventmesh.connector.jdbc.table.catalog.CatalogTable; +import org.apache.eventmesh.connector.jdbc.table.catalog.DefaultColumn; +import org.apache.eventmesh.connector.jdbc.table.catalog.PrimaryKey; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableSchema; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import com.mysql.cj.MysqlType; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MysqlDatabaseDialect extends AbstractGeneralDatabaseDialect { + + private MysqlJdbcConnection connection; + + private DataTypeConvertor dataTypeConvertor = new MysqlDataTypeConvertor(); + + private SourceConnectorConfig config; + + public MysqlDatabaseDialect(JdbcSourceConfig config) { + super(config.getSourceConnectorConfig()); + this.config = config.getSourceConnectorConfig(); + } + + @Override + public void init() { + + boolean initSuccess; + do { + try { + this.connection = initJdbcConnection(); + initSuccess = true; + } catch (Exception e) { + log.error("Init jdbc connection error,The connection will be retried in three seconds", e); + initSuccess = false; + try { + TimeUnit.SECONDS.sleep(3); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + } while (!initSuccess); + + } + + @Override + public void start() { + // TODO? + } + + private MysqlJdbcConnection initJdbcConnection() { + try { + return new MysqlJdbcConnection(config.getJdbcConfig(), null, false); + } catch (Exception e) { + throw new CatalogException(e); + } + } + + @Override + public void open() throws CatalogException { + + } + + @Override + public String getDefaultDatabase() { + return null; + } + + @Override + public boolean databaseExists(String databaseName) throws CatalogException { + if (null == databaseName || databaseName.trim().isEmpty()) { + return false; + } + List databases = listDatabases(); + return databases.contains(databaseName); + } + + @Override + public List listDatabases() throws CatalogException { + List databases = new ArrayList<>(16); + try { + this.connection.query(MysqlDialectSql.SHOW_DATABASE.ofSQL(), resultSet -> { + while (resultSet.next()) { + databases.add(resultSet.getString("Database")); + } + }); + } catch (SQLException e) { + log.error("List Mysql database error", e); + throw new CatalogException(e); + } + return databases; + } + + @Override + public List listTables(String databaseName) throws CatalogException, DatabaseNotExistException, SQLException { + + List tableIds = new ArrayList<>(32); + + // Build the SQL query to return a list of tables for the given database + String sql = MysqlDialectSql.SHOW_DATABASE_TABLE.ofWrapperSQL("`" + databaseName + "`"); + log.debug("List tables SQL:{}", sql); + this.connection.query(sql, resultSet -> { + // Execute the query and add each table ID to the list + while (resultSet.next()) { + TableId tableId = new TableId(databaseName, null, resultSet.getString(1)); + tableIds.add(tableId); + } + }); + return tableIds; + } + + @Override + public boolean tableExists(TableId tableId) throws CatalogException, SQLException { + + List tableIds = listTables(tableId.getCatalogName()); + + return tableIds.contains(tableId); + } + + @Override + public CatalogTable getTable(TableId tableId) throws CatalogException, TableNotExistException, SQLException { + + Objects.requireNonNull(tableId, "TableId is null"); + if (!tableExists(tableId)) { + log.error("Table {} not exist in database", tableId); + throw new CatalogException(String.format("Table %s not exist in database", tableId)); + } + + CatalogTable table = new CatalogTable(); + table.setTableId(tableId); + TableSchema tableSchema = new TableSchema(); + table.setTableSchema(tableSchema); + + // Get table creation SQL + final String createTableSql = MysqlDialectSql.SHOW_CREATE_TABLE.ofWrapperSQL(tableId.getId()); + log.debug("Show create table SQL:{}", createTableSql); + + this.connection.query(createTableSql, resultSet -> { + boolean hasNext = resultSet.next(); + if (!hasNext) { + throw new CatalogException(String.format("Table %s not exist in database", tableId.getId())); + } + String creatTableSql = resultSet.getString("Create Table"); + // table.setDdlSql(creatTableSql); + }); + + // Get table columns SQL + final String selectTableSql = MysqlDialectSql.SELECT_TABLE_COLUMNS.ofWrapperSQL(tableId.getId()); + log.debug("Select table SQL:{}", selectTableSql); + Map columns = new HashMap<>(16); + // Execute query to get table columns + this.connection.query(selectTableSql, resultSet -> { + ResultSetMetaData tableMetaData = resultSet.getMetaData(); + int columnCount = tableMetaData.getColumnCount(); + for (int columnIndex = 1; columnIndex <= columnCount; ++columnIndex) { + String columnName = tableMetaData.getColumnName(columnIndex); + DefaultColumn column = columns.computeIfAbsent(columnName, key -> new DefaultColumn()); + column.setName(columnName); + int precision = tableMetaData.getPrecision(columnIndex); + column.setColumnLength(precision); + Map dataTypeProperties = new HashMap<>(); + dataTypeProperties.put(MysqlDataTypeConvertor.PRECISION, precision); + int scale = tableMetaData.getScale(columnIndex); + dataTypeProperties.put(MysqlDataTypeConvertor.SCALE, scale); + column.setDataType( + dataTypeConvertor.toEventMeshType(MysqlType.getByJdbcType(tableMetaData.getColumnType(columnIndex)), dataTypeProperties)); + column.setDecimal(scale); + } + }); + + // Get table columns details SQL + final String showTableSql = MysqlDialectSql.SHOW_TABLE_COLUMNS.ofWrapperSQL(tableId.getTableName(), tableId.getCatalogName()); + log.debug("Show table columns SQL:{}", showTableSql); + // Execute query to get table columns details + List columnList = new ArrayList<>(columns.size()); + this.connection.query(showTableSql, resultSet -> { + boolean hasNext = resultSet.next(); + if (!hasNext) { + throw new CatalogException(String.format("Table %s without columns", tableId.getId())); + } + List columnNames = new ArrayList<>(4); + do { + String field = resultSet.getString("Field"); + DefaultColumn column = columns.get(field); + String comment = resultSet.getString("Comment"); + column.setComment(comment); + // The column nullability. The value is YES if NULL values can be stored in the column, NO if not. + String enableNull = resultSet.getString("Null"); + column.setNotNull("NO".equalsIgnoreCase(enableNull)); + + String type = resultSet.getString("Type"); + // column.setSqlDesc(type); + + // Get default value + Object defaultValue = resultSet.getObject("Default"); + column.setDefaultValue(defaultValue); + + String key = resultSet.getString("Key"); + if ("PRI".equalsIgnoreCase(key)) { + columnNames.add(field); + } + columnList.add(column); + } while (resultSet.next()); + tableSchema.setColumns(columnList); + tableSchema.setColumnMap(columns); + if (!columnNames.isEmpty()) { + tableSchema.setPrimaryKey(new PrimaryKey(columnNames)); + } + }); + return table; + } + + @Override + public String getName() { + return null; + } + + @Override + public PreparedStatement createPreparedStatement(Connection connection, String sql) throws SQLException { + Objects.requireNonNull(connection, "Connection is null"); + Objects.requireNonNull(sql, "SQL is null"); + return connection.prepareStatement(sql); + } + + /** + * Retrieves the JDBC driver meta-data associated with the database dialect. + * + * @return The JDBC driver meta-data. + */ + @Override + public JdbcDriverMetaData getJdbcDriverMetaData() { + return this.connection.getJdbcDriverMetaData(); + } + + /** + * Retrieves the JDBC protocol associated with the database dialect. + * + * @return The JDBC protocol. + */ + @Override + public String jdbcProtocol() { + return MysqlJdbcConnection.URL_WITH_PLACEHOLDER; + } + + /** + * Obtains a database connection. + * + * @return A database connection. + */ + @Override + public MysqlJdbcConnection getConnection() { + return this.connection; + } + + @Override + public MysqlJdbcConnection newConnection() { + return initJdbcConnection(); + } + + @Override + public void close() throws Exception { + if (this.connection != null) { + this.connection.close(); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDatabaseDialectFactory.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDatabaseDialectFactory.java new file mode 100644 index 0000000000..5f34a8a40f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDatabaseDialectFactory.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.jdbc.source.dialect.mysql; + +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.DatabaseDialectFactory; +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +public class MysqlDatabaseDialectFactory implements DatabaseDialectFactory { + + @Override + public DatabaseDialect createDatabaseDialect(SourceConfig config) { + DatabaseDialect databaseDialect = new MysqlDatabaseDialect((JdbcSourceConfig) config); + return databaseDialect; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDialectSql.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDialectSql.java new file mode 100644 index 0000000000..175ec93c99 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlDialectSql.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.connector.jdbc.source.dialect.mysql; + +public enum MysqlDialectSql { + + SHOW_DATABASE("SHOW DATABASES;", "show mysql database sql"), + + SELECT_DATABASE("USE %s", " Try to access database"), + + /** + * https://dev.mysql.com/doc/refman/8.0/en/show-tables.html + */ + SHOW_DATABASE_TABLE("SHOW FULL TABLES IN %s WHERE Table_type = 'BASE TABLE';", "show mysql database tables"), + + /** + * https://dev.mysql.com/doc/refman/8.0/en/show-columns.html + */ + SHOW_TABLE_COLUMNS("SHOW FULL COLUMNS FROM %s FROM %s;", "show mysql database table columns"), + + SELECT_TABLE_COLUMNS("SELECT * FROM %s WHERE 1=2", "show mysql database table columns"), + + /** + * https://dev.mysql.com/doc/refman/8.0/en/show-create-table.html + */ + SHOW_CREATE_TABLE("SHOW CREATE TABLE %s", "show mysql database table columns"), + + SHOW_GTID_STATUS("SHOW GLOBAL VARIABLES LIKE 'GTID_MODE'", "Show GTID_MODE Enable or not"), + + SHOW_MASTER_STATUS("SHOW MASTER STATUS", "Show master status"), + + SELECT_PURGED_GTID("SELECT @@global.gtid_purged", "SELECT the purged GTID values"), + + SHOW_GRANTS_FOR_CURRENT_USER("SHOW GRANTS FOR CURRENT_USER", "s=Show grants for current user"), + + SHOW_CREATE_DATABASE("SHOW CREATE DATABASE %s", "Show create database sql"), + + /** + * SHOW_TABLE_STATUS + */ + SHOW_TABLE_STATUS("SHOW TABLE STATUS LIKE '%s'", "Show table status"), + + SNAPSHOT_TABLE_SELECT_SQL("SELECT * FROM %s", "Select table data sql in snapshot"), + + LOCK_TABLE_GLOBAL("FLUSH TABLES WITH READ LOCK", "global lock tables"), + + LOCK_TABLES("FLUSH TABLES %s WITH READ LOCK", "lock tables"), + + UNLOCK_TABLES("UNLOCK TABLES", "unlock tables"); + + private final String sql; + + private final String desc; + + MysqlDialectSql(String sql, String desc) { + this.sql = sql; + this.desc = desc; + } + + public String ofSQL() { + return this.sql; + } + + public String ofWrapperSQL(Object... parameters) { + return String.format(this.sql, parameters); + } + + public String ofDescription() { + return this.desc; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlJdbcContext.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlJdbcContext.java new file mode 100644 index 0000000000..0dcf7ad299 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlJdbcContext.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.connector.jdbc.source.dialect.mysql; + +import org.apache.eventmesh.connector.jdbc.PartitionOffSetContextPair; +import org.apache.eventmesh.connector.jdbc.UniversalJdbcContext; +import org.apache.eventmesh.connector.jdbc.context.mysql.MysqlOffsetContext; +import org.apache.eventmesh.connector.jdbc.context.mysql.MysqlPartition; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; + +import org.apache.commons.lang3.StringUtils; + +import lombok.Getter; + +public class MysqlJdbcContext extends UniversalJdbcContext { + + @Getter + private MysqlSourceInfo sourceInfo = new MysqlSourceInfo(); + + private volatile long currentHandleEventSize = 0; + + private volatile boolean onTransaction = false; + + // need to load from store when start + private String restartGtidSet; + + private String currentGtidSet; + + private String restartBinlogFilename; + + private long restartBinlogPosition; + + private String transactionId; + + private JdbcSourceConfig jdbcSourceConfig; + + public MysqlJdbcContext(PartitionOffSetContextPair poCtx, MysqlAntlr4DdlParser parser) { + super(poCtx, parser); + } + + public MysqlJdbcContext(MysqlPartition mysqlPartition, MysqlOffsetContext mysqlOffsetContext, MysqlAntlr4DdlParser parser) { + super(mysqlPartition, mysqlOffsetContext, parser); + } + + public MysqlJdbcContext(JdbcSourceConfig jdbcSourceConfig, MysqlAntlr4DdlParser parser) { + this(new MysqlPartition(), new MysqlOffsetContext(), parser); + this.jdbcSourceConfig = jdbcSourceConfig; + } + + public void setBinlogStartPoint(String binlogFilename, long beginProcessPosition) { + assert beginProcessPosition >= 0; + if (binlogFilename != null) { + sourceInfo.setBinlogPosition(binlogFilename, beginProcessPosition); + + } else { + sourceInfo.setBinlogPosition(sourceInfo.getCurrentBinlogFileName(), beginProcessPosition); + } + } + + public void setEventPosition(long positionOfCurrentEvent, long eventSize) { + this.sourceInfo.setCurrentBinlogPosition(positionOfCurrentEvent); + this.currentHandleEventSize = eventSize; + } + + public static MysqlJdbcContext initialize(JdbcSourceConfig jdbcSourceConfig) { + SourceConnectorConfig sourceConnectorConfig = jdbcSourceConfig.getSourceConnectorConfig(); + MysqlAntlr4DdlParser mysqlAntlr4DdlParser = new MysqlAntlr4DdlParser(sourceConnectorConfig.isSkipViews(), + sourceConnectorConfig.isSkipComments(), jdbcSourceConfig); + return new MysqlJdbcContext(new MysqlPartition(), new MysqlOffsetContext(), mysqlAntlr4DdlParser); + } + + public void startTransaction() { + this.onTransaction = true; + } + + public void commitTransaction() { + this.onTransaction = false; + this.restartGtidSet = this.currentGtidSet; + this.restartBinlogFilename = sourceInfo.getCurrentBinlogFileName(); + this.restartBinlogPosition = sourceInfo.getCurrentBinlogPosition() + this.currentHandleEventSize; + resetTransactionId(); + } + + public void complete() { + this.currentHandleEventSize = 0; + } + + public void completedGtidSet(String gtidSet) { + if (StringUtils.isNotBlank(gtidSet)) { + String trimmedGtidSet = gtidSet.replace("\n", "").replace("\r", ""); + this.currentGtidSet = trimmedGtidSet; + this.restartGtidSet = trimmedGtidSet; + } + } + + public String getGtidSet() { + return this.currentGtidSet; + } + + public void beginGtid(String gtid) { + this.sourceInfo.beginGtid(gtid); + } + + private void resetTransactionId() { + transactionId = null; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlSourceInfo.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlSourceInfo.java new file mode 100644 index 0000000000..d6a0106b64 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlSourceInfo.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.connector.jdbc.source.dialect.mysql; + +import org.apache.eventmesh.connector.jdbc.common.SourceInfo; + +import lombok.Data; + +@Data +public class MysqlSourceInfo implements SourceInfo { + + private String currentBinlogFileName; + + private volatile long currentBinlogPosition = 0L; + + private int currentRowNumber = 0; + + // Support mysql gtid + private String currentGtid; + + public void setBinlogPosition(String binlogFileName, long beginProcessPosition) { + if (binlogFileName != null) { + this.currentBinlogFileName = binlogFileName; + } + assert beginProcessPosition >= 0; + this.currentBinlogPosition = beginProcessPosition; + this.currentRowNumber = 0; + } + + public void beginGtid(String gtid) { + this.currentGtid = gtid; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlSourceMateData.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlSourceMateData.java new file mode 100644 index 0000000000..bceddb1961 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/MysqlSourceMateData.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.connector.jdbc.source.dialect.mysql; + +import org.apache.eventmesh.connector.jdbc.source.SourceMateData; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * Represents MySQL-specific metadata related to a data source. + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class MysqlSourceMateData extends SourceMateData { + + /** + * The server ID of the MySQL instance. + */ + private int serverId; + + /** + * The Global Transaction Identifier (GTID) associated with the metadata. + */ + private String gtid; + + /** + * The name of the mysql binary log file. + */ + private String binlogFile; + + /** + * The position within the binary log file. + */ + private long position; + + /** + * The SQL statement associated with the metadata. + */ + private String sql; + + public static MysqlSourceMateDataBuilder newBuilder() { + return new MysqlSourceMateDataBuilder(); + } + + public static class MysqlSourceMateDataBuilder { + + private String connector = "mysql"; + private String name; + private long timestamp = System.currentTimeMillis(); + private boolean snapshot; + private String catalogName; + private String schemaName; + private String tableName; + private int serverId; + private String gtid; + private String binlogFile; + private long position; + private String sql; + + public MysqlSourceMateDataBuilder connector(String connector) { + this.connector = connector; + return this; + } + + public MysqlSourceMateDataBuilder name(String name) { + this.name = name; + return this; + } + + public MysqlSourceMateDataBuilder timestamp(long timestamp) { + this.timestamp = timestamp; + return this; + } + + public MysqlSourceMateDataBuilder snapshot(boolean snapshot) { + this.snapshot = snapshot; + return this; + } + + public MysqlSourceMateDataBuilder withTableId(TableId tableId) { + this.catalogName = tableId.getCatalogName(); + this.schemaName = tableId.getSchemaName(); + this.tableName = tableId.getTableName(); + return this; + } + + public MysqlSourceMateDataBuilder catalogName(String catalogName) { + this.catalogName = catalogName; + return this; + } + + public MysqlSourceMateDataBuilder schemaName(String schemaName) { + this.schemaName = schemaName; + return this; + } + + public MysqlSourceMateDataBuilder tableName(String tableName) { + this.tableName = tableName; + return this; + } + + public MysqlSourceMateDataBuilder serverId(int serverId) { + this.serverId = serverId; + return this; + } + + public MysqlSourceMateDataBuilder gtid(String gtid) { + this.gtid = gtid; + return this; + } + + public MysqlSourceMateDataBuilder binlogFile(String binlogFile) { + this.binlogFile = binlogFile; + return this; + } + + public MysqlSourceMateDataBuilder position(long position) { + this.position = position; + return this; + } + + public MysqlSourceMateDataBuilder sql(String sql) { + this.sql = sql; + return this; + } + + public MysqlSourceMateData build() { + MysqlSourceMateData metadata = new MysqlSourceMateData(); + metadata.setConnector(connector); + metadata.setName(name); + metadata.setTimestamp(timestamp); + metadata.setSnapshot(snapshot); + metadata.setCatalogName(catalogName); + metadata.setSchemaName(schemaName); + metadata.setTableName(tableName); + metadata.setServerId(serverId); + metadata.setGtid(gtid); + metadata.setBinlogFile(binlogFile); + metadata.setPosition(position); + metadata.setSql(sql); + return metadata; + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/StopEventData.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/StopEventData.java new file mode 100644 index 0000000000..100516f00b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/StopEventData.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.jdbc.source.dialect.mysql; + +import com.github.shyiko.mysql.binlog.event.EventData; + +public class StopEventData implements EventData { + + private static final long serialVersionUID = -7056169406695094519L; + + @Override + public String toString() { + return "StopEventData"; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/StopEventDataDeserializer.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/StopEventDataDeserializer.java new file mode 100644 index 0000000000..602d11dded --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/mysql/StopEventDataDeserializer.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.connector.jdbc.source.dialect.mysql; + +import java.io.IOException; + +import com.github.shyiko.mysql.binlog.event.deserialization.EventDataDeserializer; +import com.github.shyiko.mysql.binlog.io.ByteArrayInputStream; + +public class StopEventDataDeserializer implements EventDataDeserializer { + + @Override + public StopEventData deserialize(ByteArrayInputStream inputStream) throws IOException { + return new StopEventData(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/AbstractSnapshotEngine.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/AbstractSnapshotEngine.java new file mode 100644 index 0000000000..598068d20f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/AbstractSnapshotEngine.java @@ -0,0 +1,375 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.source.dialect.snapshot; + +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.connector.jdbc.DataChanges; +import org.apache.eventmesh.connector.jdbc.DataChanges.Builder; +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.connector.jdbc.Field; +import org.apache.eventmesh.connector.jdbc.JdbcContext; +import org.apache.eventmesh.connector.jdbc.OffsetContext; +import org.apache.eventmesh.connector.jdbc.Partition; +import org.apache.eventmesh.connector.jdbc.Payload; +import org.apache.eventmesh.connector.jdbc.Schema; +import org.apache.eventmesh.connector.jdbc.UniversalJdbcContext; +import org.apache.eventmesh.connector.jdbc.connection.JdbcConnection; +import org.apache.eventmesh.connector.jdbc.event.Event; +import org.apache.eventmesh.connector.jdbc.event.InsertDataEvent; +import org.apache.eventmesh.connector.jdbc.source.AbstractEngine; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlSourceMateData; +import org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotResult.SnapshotResultStatus; +import org.apache.eventmesh.connector.jdbc.table.catalog.Column; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableSchema; + +import org.apache.commons.collections4.CollectionUtils; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalLong; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionService; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +/** + * Abstract base class for snapshot engines. + * + * @param The Database Dialect + * @param The JDBC context type + * @param The partition type + * @param The offset context type + */ +@Slf4j +public abstract class AbstractSnapshotEngine, Jc extends JdbcContext, Part extends Partition, + Offset extends OffsetContext, Jconn extends JdbcConnection> extends AbstractEngine implements SnapshotEngine { + + private final Jconn jdbcConnection; + + private Jc context; + + private Part partition; + + private Offset offsetContext; + + protected BlockingQueue eventQueue = new LinkedBlockingQueue<>(10000); + + public AbstractSnapshotEngine(JdbcSourceConfig jdbcSourceConfig, DbDialect databaseDialect, Jc jdbcContext, Part partition, + Offset context) { + super(jdbcSourceConfig, databaseDialect); + this.context = jdbcContext; + this.partition = partition; + this.offsetContext = context; + this.jdbcConnection = databaseDialect.getConnection(); + } + + + @Override + public SnapshotResult execute() { + if (jdbcSourceConfig.getSourceConnectorConfig().isSkipSnapshot()) { + return new SnapshotResult<>(SnapshotResultStatus.SKIPPED, null); + } + SnapshotContext snapshotContext = new SnapshotContext<>(partition, offsetContext); + return doExecute(context, snapshotContext); + } + + + /** + * Template method that executes the snapshot logic. + * + * @param context the JDBC context + * @param snapshotContext the snapshot context + * @return the snapshot result + */ + protected SnapshotResult doExecute(Jc context, SnapshotContext snapshotContext) { + + Connection masterConnection = null; + Queue connectionPool = null; + try { + masterConnection = createMasterConnection(); + log.info("Snapshot 1: Preparations for Snapshot Work"); + preSnapshot(context, snapshotContext); + + log.info("Snapshot 2: Retrieve tables requiring snapshot handling"); + determineTable2Process(context, snapshotContext); + + log.info("Snapshot 3: Put locks on the tables that need to be processed"); + if (sourceConnectorConfig.isSnapshotSchema()) { + lockTables4SchemaSnapshot(context, snapshotContext); + } + + log.info("Snapshot 4: Determining snapshot offset"); + determineSnapshotOffset(context, snapshotContext); + + log.info("Snapshot 5: Obtain the schema of the captured tables"); + readStructureOfTables(context, snapshotContext); + + //Release locks + releaseSnapshotLocks(context, snapshotContext); + + //Whether to determine whether to process the table data? + if (sourceConnectorConfig.isSnapshotData()) { + connectionPool = createConnectionPool(snapshotContext); + createDataEvents(context, snapshotContext, connectionPool); + } + log.info("Snapshot 6: Release the locks"); + releaseSnapshotLocks(context, snapshotContext); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + //close connection pool's connection + try { + if (CollectionUtils.isNotEmpty(connectionPool)) { + for (JdbcConnection conn : connectionPool) { + conn.close(); + } + } + //Roll back master connection transaction + rollbackMasterConnTransaction(masterConnection); + } catch (Exception e) { + log.warn("Handle snapshot finally error", e); + } + } + return new SnapshotResult<>(SnapshotResultStatus.COMPLETED, context); + } + + private void rollbackMasterConnTransaction(Connection connection) { + if (connection != null) { + try { + connection.rollback(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + } + + private Connection createMasterConnection() throws SQLException { + JdbcConnection connection = databaseDialect.getConnection(); + connection.setAutoCommit(false); + return connection.connection(); + } + + /** + * Creates data events. + * + * @param context The context. + * @param snapshotContext The snapshot context. + * @param connectionPool The connection pool. + * @throws SQLException If an error occurs. + */ + private void createDataEvents(Jc context, SnapshotContext snapshotContext, Queue connectionPool) + throws Exception { + + int handleDataThreadNum = connectionPool.size(); + //Create thread pool to process table data + ThreadPoolExecutor tableDataPoolExecutor = ThreadPoolFactory.createThreadPoolExecutor(handleDataThreadNum, handleDataThreadNum, + "snapshot-table-data-thread"); + CompletionService completionService = new ExecutorCompletionService<>(tableDataPoolExecutor); + try { + for (TableId tableId : snapshotContext.determineTables) { + String sql = getSnapshotTableSelectSql(context, snapshotContext, tableId).get(); + Callable callable = createSnapshotDataEvent4TableCallable(context, snapshotContext, connectionPool, sql, tableId); + completionService.submit(callable); + } + int tableSize = snapshotContext.determineTables.size(); + for (int index = 0; index < tableSize; ++index) { + completionService.take().get(); + } + } finally { + tableDataPoolExecutor.shutdownNow(); + } + } + + private Callable createSnapshotDataEvent4TableCallable(Jc context, SnapshotContext snapshotContext, + Queue connectionPool, String sql, TableId tableId) { + UniversalJdbcContext universalJdbcContext = (UniversalJdbcContext) context; + universalJdbcContext.withTableId(tableId); + return () -> { + JdbcConnection connection = connectionPool.poll(); + MysqlSourceMateData sourceMateData = MysqlSourceMateData.newBuilder() + .name(sourceConnectorConfig.getName()) + .snapshot(true) + .withTableId(tableId) + .serverId(sourceConnectorConfig.getMysqlConfig().getServerId()) + .build(); + TableSchema tableSchema = universalJdbcContext.getCatalogTableSet().getTableSchema(tableId); + Field field = new Field().withField("after").withType("field").withName("payload.after").withRequired(false); + List columns = tableSchema.getColumns(); + if (CollectionUtils.isNotEmpty(columns)) { + List fields = columns.stream() + .map(col -> new Field(col.getDataType().getName(), col.isNotNull(), col.getName(), tableId.toString())) + .collect(Collectors.toList()); + field.withRequired(true).withFields(fields); + } + try (Statement statement = connection.createStatement(jdbcSourceConfig.getSourceConnectorConfig().getSnapshotFetchSize(), 100)) { + ResultSet resultSet = statement.executeQuery(sql); + while (resultSet.next()) { + int columnCount = resultSet.getMetaData().getColumnCount(); + InsertDataEvent event = new InsertDataEvent(tableId); + Payload payload = event.getJdbcConnectData().getPayload(); + Map values = new HashMap<>(columnCount); + for (int index = 1; index <= columnCount; ++index) { + values.put(resultSet.getMetaData().getColumnName(index), resultSet.getObject(index)); + } + Builder builder = DataChanges.newBuilder(); + builder.withAfter(values); + payload.withDataChanges(builder.build()); + payload.withSource(sourceMateData); + event.getJdbcConnectData().setSchema(new Schema(Collections.singletonList(field))); + eventQueue.put(event); + } + } finally { + connectionPool.add(connection); + } + return null; + }; + } + + private Queue createConnectionPool(final SnapshotContext snapshotContext) throws SQLException { + Queue connectionPool = new ConcurrentLinkedQueue<>(); + int snapshotMaxThreads = Math.max(1, + Math.min(this.jdbcSourceConfig.getSourceConnectorConfig().getSnapshotMaxThreads(), snapshotContext.determineTables.size())); + + for (int i = 0; i < snapshotMaxThreads; i++) { + JdbcConnection conn = databaseDialect.newConnection().setAutoCommit(false); + //Get transaction isolation from master connection and then set to connection of pool + conn.connection().setTransactionIsolation(jdbcConnection.connection().getTransactionIsolation()); + connectionPool.add(conn); + } + log.info("Created connection pool with {} number", snapshotMaxThreads); + return connectionPool; + } + + /** + * Pre-snapshot preparations. + * + * @param jdbcContext the JDBC context + * @param snapshotContext the snapshot context + */ + protected abstract void preSnapshot(Jc jdbcContext, SnapshotContext snapshotContext); + + /** + * Determine tables that need snapshotting. + * + * @param jdbcContext the JDBC context + * @param snapshotContext the snapshot context + */ + protected abstract void determineTable2Process(Jc jdbcContext, SnapshotContext snapshotContext); + + /** + * Lock tables for consistent snapshot schema. + * + * @param jdbcContext the JDBC context + * @param snapshotContext the snapshot context + * @throws SQLException if a database error occurs + */ + protected abstract void lockTables4SchemaSnapshot(Jc jdbcContext, SnapshotContext snapshotContext) throws SQLException; + + /** + * Determine snapshot offset. + * + * @param jdbcContext the JDBC context + * @param snapshotContext the snapshot context + * @throws SQLException if a database error occurs + */ + protected abstract void determineSnapshotOffset(Jc jdbcContext, SnapshotContext snapshotContext) throws SQLException; + + /** + * Read and store table schemas. + * + * @param jdbcContext the JDBC context + * @param snapshotContext the snapshot context + * @throws SQLException if a database error occurs + * @throws InterruptedException if interrupted + */ + protected abstract void readStructureOfTables(Jc jdbcContext, SnapshotContext snapshotContext) + throws SQLException, InterruptedException; + + /** + * Release locks after snapshot. + * + * @param jdbcContext the JDBC context + * @param snapshotContext the snapshot context + */ + protected abstract void releaseSnapshotLocks(Jc jdbcContext, SnapshotContext snapshotContext) throws Exception; + + protected abstract Optional getSnapshotTableSelectSql(Jc jdbcContext, SnapshotContext snapshotContext, TableId tableId); + + protected OptionalLong getRowCount4Table(TableId tableId) { + return OptionalLong.empty(); + } + + public static class SnapshotContext

implements AutoCloseable { + + protected P partition; + + protected O offset; + + protected Set determineTables = new HashSet<>(); + + public SnapshotContext(P partition, O offset) { + this.partition = partition; + this.offset = offset; + } + + @Override + public void close() throws Exception { + + } + + public void add(TableId tableId) { + SnapshotContext.this.determineTables.add(tableId); + } + + public void addAll(Set tableIds) { + if (tableIds != null) { + SnapshotContext.this.determineTables.addAll(tableIds); + } + } + + public P getPartition() { + return partition; + } + + public O getOffset() { + return offset; + } + + public Set getDetermineTables() { + return determineTables; + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotEngine.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotEngine.java new file mode 100644 index 0000000000..727abcea0f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotEngine.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.connector.jdbc.source.dialect.snapshot; + +import org.apache.eventmesh.connector.jdbc.JdbcContext; +import org.apache.eventmesh.connector.jdbc.event.EventConsumer; +import org.apache.eventmesh.connector.jdbc.source.Engine; + +/** + * The SnapshotEngine interface extends the Engine interface and represents an engine capable of performing snapshots. + * + * @param The type of JdbcContext used for the snapshot. + */ +public interface SnapshotEngine extends Engine, AutoCloseable { + + /** + * Executes the snapshot operation and returns the result containing the snapshot offset. + * + * @return The SnapshotResult containing the snapshot offset. + */ + SnapshotResult execute(); + + /** + * Registers a SnapshotEventConsumer to receive snapshot events from the engine. + * + * @param consumer The SnapshotEventConsumer to register. + */ + void registerSnapshotEventConsumer(EventConsumer consumer); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotEngineFactory.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotEngineFactory.java new file mode 100644 index 0000000000..164b5b97b4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotEngineFactory.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.connector.jdbc.source.dialect.snapshot; + +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.connector.jdbc.JdbcContext; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +/** + * The SnapshotEngineFactory interface represents a factory for creating snapshot engines. It provides a method to create a snapshot engine based on + * the given configuration and database dialect. + */ +@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.JDBC_SNAPSHOT_ENGINE) +public interface SnapshotEngineFactory { + + /** + * Creates a snapshot engine with the specified JDBC source configuration and database dialect. + * + * @param jdbcSourceConfig The JDBC source configuration. + * @param databaseDialect The database dialect. + * @return A snapshot engine that can perform snapshot operations. + */ + SnapshotEngine createSnapshotEngine(final JdbcSourceConfig jdbcSourceConfig, + final DatabaseDialect databaseDialect); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotResult.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotResult.java new file mode 100644 index 0000000000..d36c85468c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotResult.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.connector.jdbc.source.dialect.snapshot; + +import org.apache.eventmesh.connector.jdbc.JdbcContext; + +import lombok.Getter; + +@Getter +public class SnapshotResult { + + private final SnapshotResultStatus status; + + private final Jc context; + + public SnapshotResult(SnapshotResultStatus status, Jc jc) { + this.status = status; + this.context = jc; + } + + public enum SnapshotResultStatus { + COMPLETED, + ABORTED, + SKIPPED + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotType.java new file mode 100644 index 0000000000..9f995f689c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/SnapshotType.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.connector.jdbc.source.dialect.snapshot; + +public enum SnapshotType { + + /** + * Every time the service starts, it reads the data of the tables that need to be processed. + */ + INITIALIZATION, + + /** + * Continue processing from the last handled position. + */ + INCREASE // TODO Need to support next version +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/mysql/MysqlSnapshotEngine.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/mysql/MysqlSnapshotEngine.java new file mode 100644 index 0000000000..2d4a7c2d31 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/mysql/MysqlSnapshotEngine.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.connector.jdbc.source.dialect.snapshot.mysql; + +import org.apache.eventmesh.connector.jdbc.connection.mysql.MysqlJdbcConnection; +import org.apache.eventmesh.connector.jdbc.context.mysql.MysqlOffsetContext; +import org.apache.eventmesh.connector.jdbc.context.mysql.MysqlPartition; +import org.apache.eventmesh.connector.jdbc.event.Event; +import org.apache.eventmesh.connector.jdbc.event.EventConsumer; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.config.MysqlConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlConstants; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlDatabaseDialect; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlDialectSql; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlJdbcContext; +import org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.AbstractSnapshotEngine; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.utils.MysqlUtils; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; +import java.util.OptionalLong; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MysqlSnapshotEngine extends + AbstractSnapshotEngine { + + private volatile boolean globalLockAcquired = false; + + private volatile boolean tableLockAcquired = false; + + private List consumers = new ArrayList<>(16); + + private MysqlJdbcConnection connection; + + public MysqlSnapshotEngine(JdbcSourceConfig jdbcSourceConfig, MysqlDatabaseDialect databaseDialect, MysqlJdbcContext jdbcContext) { + super(jdbcSourceConfig, databaseDialect, jdbcContext, jdbcContext.getPartition(), jdbcContext.getOffsetContext()); + this.connection = databaseDialect.getConnection(); + jdbcContext.getParser().addTableIdSet(getHandledTables()); + } + + @Override + protected Set defaultExcludeDatabase() { + return MysqlConstants.DEFAULT_EXCLUDE_DATABASE; + } + + @Override + public void close() throws Exception { + shutdown(); + } + + @Override + protected void preSnapshot(MysqlJdbcContext jdbcContext, SnapshotContext snapshotContext) { + // nothing to do + } + + @Override + protected void determineTable2Process(MysqlJdbcContext jdbcContext, SnapshotContext snapshotContext) { + snapshotContext.addAll(getHandledTables()); + } + + @Override + protected void lockTables4SchemaSnapshot(MysqlJdbcContext jdbcContext, SnapshotContext snapshotContext) + throws SQLException { + // Set the REPEATABLE_READ isolation level to avoid the MySQL transaction isolation level being changed unexpectedly. + connection.connection().setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); + connection.executeWithoutCommitting("SET SESSION lock_wait_timeout=10", "SET SESSION innodb_lock_wait_timeout=10"); + + // Lock tables + final MysqlConfig mysqlConfig = sourceConnectorConfig.getMysqlConfig(); + if (mysqlConfig.getSnapshotLockingMode().usesLocking() && mysqlConfig.isUseGlobalLock()) { + globalLockAcquiredTry(); + } + + } + + @Override + protected void determineSnapshotOffset(MysqlJdbcContext jdbcContext, SnapshotContext snapshotContext) + throws SQLException { + + if (!globalLockAcquired && !tableLockAcquired) { + return; + } + log.info("Read binlog info from Mysql Server"); + /** + * The result of executing the SHOW MASTER STATUS script is as follows: + * +-----------------+----------+--------------+------------------+-------------------------------------------+ + * | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | + * +-----------------+----------+--------------+------------------+-------------------------------------------+ + * | mysqlbin.000009 | 197 | | | 71a89bf3-0dd0-11ee-98b2-0242ac110002:1-76 | + * +-----------------+----------+--------------+------------------+-------------------------------------------+ + */ + connection.query(MysqlDialectSql.SHOW_MASTER_STATUS.ofSQL(), resultSet -> { + if (resultSet.next()) { + final String binlogFilename = resultSet.getString(1); + final long position = resultSet.getLong(2); + jdbcContext.setBinlogStartPoint(binlogFilename, position); + if (resultSet.getMetaData().getColumnCount() >= 5) { + final String gtidSet = resultSet.getString(5); + jdbcContext.completedGtidSet(gtidSet); + log.info("Using binlog '{}' at position '{}' and gtid '{}'", binlogFilename, position, gtidSet); + } else { + log.info("Using binlog '{}' at position '{}' ", binlogFilename, position); + } + } else { + throw new SQLException("Cannot read the binlog filename and position,Make sure Mysql server is correctly configured"); + } + }); + } + + @Override + protected void readStructureOfTables(MysqlJdbcContext jdbcContext, SnapshotContext snapshotContext) + throws SQLException, InterruptedException { + if (sourceConnectorConfig.getMysqlConfig().getSnapshotLockingMode().usesLocking() && !globalLockAcquired) { + lockTable(snapshotContext); + determineSnapshotOffset(jdbcContext, snapshotContext); + } + // Parse all Databases from the tableId, construct creation statements + Set determineTables = snapshotContext.getDetermineTables(); + for (TableId tableId : determineTables) { + StringBuilder dropTableDdl = new StringBuilder("DROP TABLE IF EXISTS "); + dropTableDdl.append(MysqlUtils.wrapper(tableId)); + addParseDdlAndEvent(jdbcContext, dropTableDdl.toString(), tableId); + } + final HashMap/* table list */> databaseMapTables = determineTables.stream() + .collect(Collectors.groupingBy(TableId::getCatalogName, HashMap::new, Collectors.toList())); + Set databaseSet = databaseMapTables.keySet(); + // Read all table structures, construct DDL statements + for (String database : databaseSet) { + StringBuilder dropDatabaseDdl = new StringBuilder("DROP DATABASE IF EXISTS ").append(MysqlUtils.wrapper(database)); + addParseDdlAndEvent(jdbcContext, dropDatabaseDdl.toString(), new TableId(database)); + String databaseCreateDdl = connection.query(MysqlDialectSql.SHOW_CREATE_DATABASE.ofWrapperSQL(MysqlUtils.wrapper(database)), rs -> { + if (rs.next() && rs.getMetaData().getColumnCount() > 1) { + String ddl = rs.getString(2); + return ddl; + } + return null; + }); + if (StringUtils.isBlank(databaseCreateDdl)) { + log.warn("Database {} ddl is empty", database); + continue; + } + TableId tableId = new TableId(database); + addParseDdlAndEvent(jdbcContext, databaseCreateDdl, tableId); + addParseDdlAndEvent(jdbcContext, "USE " + database, tableId); + + // build create table snapshot event + List tableIds = databaseMapTables.get(database); + createTableSnapshotEvent(tableIds, jdbcContext); + } + } + + private void addParseDdlAndEvent(MysqlJdbcContext jdbcContext, String ddl, TableId tableId) { + jdbcContext.getParser().setCurrentDatabase(tableId.getCatalogName()); + jdbcContext.getParser().setCatalogTableSet(jdbcContext.getCatalogTableSet()); + jdbcContext.getParser().parse(ddl, event -> { + try { + if (event == null) { + return; + } + event.getJdbcConnectData().getPayload().ofSourceMateData().setSnapshot(true); + eventQueue.put(event); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + } + + private void createTableSnapshotEvent(List tableIds, MysqlJdbcContext jdbcContext) throws SQLException { + if (CollectionUtils.isEmpty(tableIds)) { + return; + } + for (TableId tableId : tableIds) { + connection.query(MysqlDialectSql.SHOW_CREATE_TABLE.ofWrapperSQL(tableId.toString()), resultSet -> { + if (resultSet.next()) { + // Get create table sql + String createTableDdl = resultSet.getString(2); + addParseDdlAndEvent(jdbcContext, createTableDdl, tableId); + } + }); + } + } + + private void lockTable(SnapshotContext snapshotContext) throws SQLException { + + Boolean lockedTable = connection.query(MysqlDialectSql.SHOW_GRANTS_FOR_CURRENT_USER.ofSQL(), rs -> { + while (rs.next()) { + String grantPrivilege = rs.getString(1); + if (StringUtils.isBlank(grantPrivilege)) { + continue; + } + if (StringUtils.containsAny(grantPrivilege.toUpperCase(), "ALL", "LOCK TABLES")) { + return true; + } + } + return false; + }); + if (!lockedTable) { + throw new SQLException("Current User does not have the 'LOCK TABLES' privilege"); + } + if (CollectionUtils.isNotEmpty(snapshotContext.getDetermineTables())) { + /** + * FLUSH + */ + String tableNameList = snapshotContext.getDetermineTables().stream().map(TableId::toString).collect(Collectors.joining(",")); + connection.executeWithoutCommitting(MysqlDialectSql.LOCK_TABLES.ofWrapperSQL(tableNameList)); + } + tableLockAcquired = true; + } + + @Override + protected void releaseSnapshotLocks(MysqlJdbcContext jdbcContext, SnapshotContext snapshotContext) + throws Exception { + if (globalLockAcquired) { + connection.executeWithoutCommitting(MysqlDialectSql.UNLOCK_TABLES.ofSQL()); + globalLockAcquired = false; + } + if (tableLockAcquired) { + connection.executeWithoutCommitting(MysqlDialectSql.UNLOCK_TABLES.ofSQL()); + globalLockAcquired = false; + } + } + + @Override + protected Optional getSnapshotTableSelectSql(MysqlJdbcContext jdbcContext, + SnapshotContext snapshotContext, TableId tableId) { + return Optional.of(MysqlDialectSql.SNAPSHOT_TABLE_SELECT_SQL.ofWrapperSQL(tableId.toString())); + } + + private void globalLockAcquiredTry() throws SQLException { + // Lock tables + connection.executeWithoutCommitting(MysqlDialectSql.LOCK_TABLE_GLOBAL.ofSQL()); + this.globalLockAcquired = true; + } + + @Override + public String getThreadName() { + return this.getClass().getSimpleName() + "-thread"; + } + + @Override + public void run() { + while (isRunning) { + try { + Event event = eventQueue.poll(5, TimeUnit.SECONDS); + if (null == event) { + continue; + } + consumers.forEach(consumer -> consumer.accept(event)); + } catch (Exception e) { + log.warn("Consume snapshot event error", e); + } + } + } + + @Override + public void init() { + + } + + @Override + public void registerSnapshotEventConsumer(EventConsumer consumer) { + if (consumer == null) { + return; + } + consumers.add(consumer); + } + + @Override + protected OptionalLong getRowCount4Table(TableId tableId) { + return connection.getRowCount4Table(tableId); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/mysql/MysqlSnapshotEngineFactory.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/mysql/MysqlSnapshotEngineFactory.java new file mode 100644 index 0000000000..53c5f993da --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/source/dialect/snapshot/mysql/MysqlSnapshotEngineFactory.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.jdbc.source.dialect.snapshot.mysql; + +import org.apache.eventmesh.connector.jdbc.DatabaseDialect; +import org.apache.eventmesh.connector.jdbc.source.config.JdbcSourceConfig; +import org.apache.eventmesh.connector.jdbc.source.dialect.antlr4.mysql.MysqlAntlr4DdlParser; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlDatabaseDialect; +import org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlJdbcContext; +import org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotEngine; +import org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotEngineFactory; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MysqlSnapshotEngineFactory implements SnapshotEngineFactory { + + @Override + public SnapshotEngine createSnapshotEngine(final JdbcSourceConfig jdbcSourceConfig, + final DatabaseDialect databaseDialect) { + return new MysqlSnapshotEngine(jdbcSourceConfig, (MysqlDatabaseDialect) databaseDialect, + new MysqlJdbcContext(jdbcSourceConfig, new MysqlAntlr4DdlParser(false, false, jdbcSourceConfig))); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/AbstractColumnEditorImpl.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/AbstractColumnEditorImpl.java new file mode 100644 index 0000000000..146d232a2d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/AbstractColumnEditorImpl.java @@ -0,0 +1,287 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.table.catalog; + +import org.apache.eventmesh.connector.jdbc.table.type.EventMeshDataType; + +import java.sql.JDBCType; + +public abstract class AbstractColumnEditorImpl implements ColumnEditor { + + /** + * Name of the column + */ + private String name; + + /** + * Data type of the column + */ + private EventMeshDataType eventMeshDataType; + + /** + * Length of the column + */ + private Integer columnLength; + + /** + * Decimal point of the column + */ + private Integer scale; + + /** + * Indicates if the column can be null or not + */ + private boolean notNull; + + /** + * Comment for the column + */ + private String comment; + + /** + * Default value for the column + */ + private Object defaultValue; + + private String typeName; + + private JDBCType jdbcType; + + private String defaultValueExpression; + + private boolean optional; + + private int order; + + public AbstractColumnEditorImpl(String name) { + this.name = name; + } + + public AbstractColumnEditorImpl() { + } + + /** + * Sets the name of the column. + * + * @param name The name of the column. + * @return The column editor instance. + */ + @Override + @SuppressWarnings("unchecked") + public CE withName(String name) { + this.name = name; + return (CE) this; + } + + /** + * Retrieves the name associated with this column editor. + * + * @return The name of the column. + */ + @Override + public String ofName() { + return this.name; + } + + /** + * Sets the data type of the column. + * + * @param typeName The data type name of the column. + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE withType(String typeName) { + this.typeName = typeName; + return (CE) this; + } + + /** + * Sets the JDBC data type of the column. + * + * @param jdbcType The JDBC data type of the column. + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE withJdbcType(JDBCType jdbcType) { + this.jdbcType = jdbcType; + return (CE) this; + } + + /** + * Sets the EventMesh data type of the column. + * + * @param eventMeshType The EventMesh data type of the column. + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE withEventMeshType(EventMeshDataType eventMeshType) { + this.eventMeshDataType = eventMeshType; + return (CE) this; + } + + /** + * Sets the order or position of the column within a table. + * + * @param order The order or position of the column. + * @return The column editor instance. + */ + @Override + @SuppressWarnings("unchecked") + public CE withOrder(int order) { + this.order = order; + return (CE) this; + } + + /** + * Sets the length of the column (if applicable). + * + * @param length The length of the column. + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE length(int length) { + this.columnLength = length; + return (CE) this; + } + + /** + * Sets the scale of the column (if applicable). + * + * @param scale The scale of the column. + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE scale(Integer scale) { + this.scale = scale; + return (CE) this; + } + + /** + * Sets whether the column is optional (nullable). + * + * @param optional Indicates whether the column is optional (true) or not (false). + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE optional(boolean optional) { + this.optional = optional; + return (CE) this; + } + + /** + * Sets the comment for the column. + * + * @param comment The comment for the column. + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE comment(String comment) { + this.comment = comment; + return (CE) this; + } + + /** + * Sets the default value expression for the column. + * + * @param defaultValueExpression The default value expression for the column. + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE defaultValueExpression(String defaultValueExpression) { + this.defaultValueExpression = defaultValueExpression; + return (CE) this; + } + + /** + * Sets the default value for the column. + * + * @param value The default value for the column. + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE defaultValue(Object value) { + this.defaultValue = value; + return (CE) this; + } + + /** + * Sets whether the column is marked as not null. + * + * @param notNull Indicates whether the column is marked as not null (true) or not (false). + * @return The column editor instance. + */ + @SuppressWarnings("unchecked") + @Override + public CE notNull(boolean notNull) { + this.notNull = notNull; + return (CE) this; + } + + public EventMeshDataType ofEventMeshDataType() { + return eventMeshDataType; + } + + public Integer ofColumnLength() { + return columnLength; + } + + public Integer ofScale() { + return scale; + } + + public boolean isNotNull() { + return notNull; + } + + public String ofComment() { + return comment; + } + + public Object ofDefaultValue() { + return defaultValue; + } + + public String ofTypeName() { + return typeName; + } + + public JDBCType ofJdbcType() { + return jdbcType; + } + + public String ofDefaultValueExpression() { + return defaultValueExpression; + } + + public boolean isOptional() { + return optional; + } + + public int ofOrder() { + return this.order; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/AbstractTableEditorImpl.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/AbstractTableEditorImpl.java new file mode 100644 index 0000000000..61a7c7bf3f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/AbstractTableEditorImpl.java @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.jdbc.table.catalog; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class AbstractTableEditorImpl implements + TableEditor { + + private TableId tableId; + + private PrimaryKey primaryKey = new PrimaryKey(); + + private List uniqueKeys = new ArrayList<>(8); + + private Map columns = new HashMap<>(16); + + private String comment; + + private Options options = new Options(); + + public AbstractTableEditorImpl(TableId tableId) { + this.tableId = tableId; + } + + public AbstractTableEditorImpl() { + } + + /** + * Sets the unique identifier (ID) of the table. + * + * @param tableId The unique ID of the table. + * @return A reference to the table editor for further configuration. + */ + @Override + @SuppressWarnings("unchecked") + public TE withTableId(TableId tableId) { + this.tableId = tableId; + return (TE) this; + } + + /** + * Adds columns to the table. + * + * @param columns The columns to add to the table. + * @return A reference to the table editor for further configuration. + */ + @Override + @SuppressWarnings("unchecked") + public TE addColumns(Col... columns) { + if (columns != null && columns.length > 0) { + for (Col column : columns) { + this.columns.put(column.getName(), column); + } + } + return (TE) this; + } + + /** + * Sets a comment or description for the table. + * + * @param comment A comment or description for the table. + * @return A reference to the table editor for further configuration. + */ + @Override + @SuppressWarnings("unchecked") + public TE withComment(String comment) { + this.comment = comment; + return (TE) this; + } + + /** + * Removes a column from the table. + * + * @param columnName The name of the column to remove. + * @return A reference to the table editor for further configuration. + */ + @Override + @SuppressWarnings("unchecked") + public TE removeColumn(String columnName) { + this.columns.remove(columnName); + return (TE) this; + } + + /** + * Sets the primary key columns for the table. + * + * @param pkColumnNames The names of the columns that form the primary key. + * @param comment A comment or description for the primary key. + * @return A reference to the table editor for further configuration. + */ + @Override + @SuppressWarnings("unchecked") + public TE withPrimaryKeyNames(List pkColumnNames, String comment) { + this.primaryKey = new PrimaryKey(pkColumnNames, comment); + return (TE) this; + } + + /** + * Sets the primary key columns for the table. + * + * @param pkColumnNames The names of the columns that form the primary key. + * @return A reference to the table editor for further configuration. + */ + @Override + @SuppressWarnings("unchecked") + public TE withPrimaryKeyNames(String... pkColumnNames) { + if (pkColumnNames != null && pkColumnNames.length > 0) { + primaryKey.addColumnNames(pkColumnNames); + } + return (TE) this; + } + + /** + * Sets the primary key for the table. + * + * @param primaryKey The primary key definition. + * @return A reference to the table editor for further configuration. + */ + @Override + @SuppressWarnings("unchecked") + public TE withPrimaryKey(PrimaryKey primaryKey) { + this.primaryKey = primaryKey; + return (TE) this; + } + + /** + * Sets the unique key columns and their names for the table. + * + * @param ukName The name of the unique key constraint. + * @param ukColumnNames The names of the columns that form the unique key. + * @param comment A comment or description for the unique key. + * @return A reference to the table editor for further configuration. + */ + @Override + @SuppressWarnings("unchecked") + public TE withUniqueKeyColumnsNames(String ukName, List ukColumnNames, String comment) { + this.uniqueKeys.add(new UniqueKey(ukName, ukColumnNames, comment)); + return (TE) this; + } + + /** + * Sets the unique key constraints for the table. + * + * @param uniqueKeys The unique key constraints. + * @return A reference to the table editor for further configuration. + */ + @Override + @SuppressWarnings("unchecked") + public TE withUniqueKeys(UniqueKey... uniqueKeys) { + if (uniqueKeys != null && uniqueKeys.length > 0) { + for (UniqueKey uniqueKey : uniqueKeys) { + this.uniqueKeys.add(uniqueKey); + } + } + return (TE) this; + } + + /** + * @param key + * @param value + * @return + */ + @Override + @SuppressWarnings("unchecked") + public TE withOption(String key, Object value) { + this.options.put(key, value); + return (TE) this; + } + + protected TableId ofTableId() { + return tableId; + } + + protected PrimaryKey ofPrimaryKey() { + return primaryKey; + } + + protected List ofUniqueKeys() { + return uniqueKeys; + } + + protected Map ofColumns() { + return columns; + } + + protected String ofComment() { + return comment; + } + + protected Options ofOptions() { + return options; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Catalog.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Catalog.java new file mode 100644 index 0000000000..d0a1fa2996 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Catalog.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.connector.jdbc.table.catalog; + +import org.apache.eventmesh.connector.jdbc.exception.CatalogException; +import org.apache.eventmesh.connector.jdbc.exception.DatabaseNotExistException; +import org.apache.eventmesh.connector.jdbc.exception.TableNotExistException; + +import java.sql.SQLException; +import java.util.List; + +/** + * Interacting with a catalog of databases and tables. + */ +public interface Catalog extends AutoCloseable { + + /** + * Opens the catalog. + * + * @throws CatalogException if there is an error opening the catalog. + */ + void open() throws CatalogException; + + /** + * Gets the name of the default database. + * + * @return the name of the default database. + */ + String getDefaultDatabase(); + + /** + * Checks if a database with the given name exists. + * + * @param databaseName the name of the database to check. + * @return true if the database exists, false otherwise. + * @throws CatalogException if there is an error checking for the database. + */ + boolean databaseExists(String databaseName) throws CatalogException; + + /** + * Gets a list of all databases in the catalog. + * + * @return a list of all databases in the catalog. + * @throws CatalogException if there is an error getting the list of databases. + */ + List listDatabases() throws CatalogException; + + /** + * Gets a list of all tables in the given database. + * + * @param databaseName the name of the database to get the tables for. + * @return a list of all tables in the given database. + * @throws CatalogException if there is an error getting the list of tables. + * @throws DatabaseNotExistException if the database does not exist. + * @throws SQLException if there is an error accessing the database. + */ + List listTables(String databaseName) throws CatalogException, DatabaseNotExistException, SQLException; + + /** + * Checks if a table with the given ID exists. + * + * @param tableId the ID of the table to check. + * @return true if the table exists, false otherwise. + * @throws CatalogException if there is an error checking for the table. + * @throws SQLException if there is an error accessing the database. + */ + boolean tableExists(TableId tableId) throws CatalogException, SQLException; + + /** + * Gets the table with the given ID. + * + * @param tableId the ID of the table to get. + * @return the table with the given ID. + * @throws CatalogException if there is an error getting the table. + * @throws TableNotExistException if the table does not exist. + * @throws SQLException if there is an error accessing the database. + */ + CatalogTable getTable(TableId tableId) throws CatalogException, TableNotExistException, SQLException; + + // TODO: support create table, drop table and update table +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/CatalogSchema.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/CatalogSchema.java new file mode 100644 index 0000000000..2caae2a841 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/CatalogSchema.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.connector.jdbc.table.catalog; + +import java.io.Serializable; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Represents catalog schema information, including its name and character set. + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CatalogSchema implements Serializable { + + /** + * The name of the catalog schema. + */ + private String name; + + /** + * The character set used by the catalog schema. + */ + private String characterSet; + + public CatalogSchema(String name) { + this.name = name; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/CatalogTable.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/CatalogTable.java new file mode 100644 index 0000000000..4aa2b89351 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/CatalogTable.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.connector.jdbc.table.catalog; + +import java.io.Serializable; + +import lombok.Data; + +/** + * Represents a catalog table. + */ +@Data +public class CatalogTable implements Serializable { + + private static final long serialVersionUID = -9159821671858779282L; + + // The ID of the table. + private TableId tableId; + + // The schema of the table. + private TableSchema tableSchema; + + // A comment describing the table. + private String comment; + + private Options options; + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/CatalogTableSet.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/CatalogTableSet.java new file mode 100644 index 0000000000..ed2b6dc6e4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/CatalogTableSet.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.connector.jdbc.table.catalog; + +import org.apache.commons.lang3.StringUtils; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public final class CatalogTableSet { + + private final TableIdSet tableIdSet; + + private final TableSchemaMap tableSchemaMap; + + public CatalogTableSet() { + + this.tableIdSet = new TableIdSet(); + this.tableSchemaMap = new TableSchemaMap(); + + } + + public void removeDatabase(String catalogName) { + removeDatabase(catalogName, null); + } + + public void removeDatabase(String catalogName, String schemaName) { + tableSchemaMap.removeDatabase(catalogName, schemaName); + tableIdSet.removeDatabase(catalogName, schemaName); + } + + public void overrideTable(TableSchema tableSchema) { + if (tableSchema == null || tableSchema.getTableId() == null) { + return; + } + tableSchemaMap.putTableSchema(tableSchema); + } + + public TableSchema getTableSchema(TableId tableId) { + return tableSchemaMap.getTableSchema(tableId); + } + + private static class TableIdSet { + + private final Set values; + + public TableIdSet() { + values = new HashSet<>(32); + } + + public void removeDatabase(String catalogName, String schemaName) { + values.removeIf( + entry -> StringUtils.equals(entry.getCatalogName(), catalogName) && StringUtils.equals(entry.getSchemaName(), schemaName)); + } + } + + private static class TableSchemaMap { + + private final ConcurrentMap values; + + public TableSchemaMap() { + this.values = new ConcurrentHashMap<>(32); + } + + public void removeDatabase(String catalogName, String schemaName) { + values.entrySet().removeIf(entry -> { + TableId key = entry.getKey(); + return StringUtils.equals(key.getCatalogName(), catalogName) && StringUtils.equals(key.getSchemaName(), schemaName); + }); + } + + public TableSchema getTableSchema(TableId tableId) { + return values.get(tableId); + } + + public TableSchema putTableSchema(TableSchema tableSchema) { + return values.put(tableSchema.getTableId(), tableSchema); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Column.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Column.java new file mode 100644 index 0000000000..94ed25f24e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Column.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.connector.jdbc.table.catalog; + +import org.apache.eventmesh.connector.jdbc.table.type.EventMeshDataType; + +import java.io.Serializable; +import java.sql.JDBCType; +import java.sql.Types; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Column of {@link TableSchema}. + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public abstract class Column implements Serializable { + + /** + * Name of the column + */ + protected String name; + + /** + * Data type of the column + */ + protected EventMeshDataType dataType; + + /** + * {@link Types JDBC type} + */ + protected JDBCType jdbcType; + + /** + * Length of the column + */ + protected Integer columnLength; + + /** + * Decimal point of the column + */ + protected Integer decimal; + + /** + * Indicates if the column can be null or not + */ + protected boolean notNull; + + /** + * Comment for the column + */ + protected String comment; + + /** + * Default value for the column + */ + protected Object defaultValue; + + protected String defaultValueExpression; + + protected int order; + + /** + * creates a clone of the Column + * + * @return clone of column + */ + public abstract Col clone(); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/ColumnEditor.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/ColumnEditor.java new file mode 100644 index 0000000000..2661c7db27 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/ColumnEditor.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.connector.jdbc.table.catalog; + +import org.apache.eventmesh.connector.jdbc.table.type.EventMeshDataType; + +import java.sql.JDBCType; + +/** + * An interface for building and configuring columns in a database table. + * + * @param The concrete type of the column editor. + * @param The concrete type of the column being edited. + */ +public interface ColumnEditor { + + /** + * Sets the name of the column. + * + * @param name The name of the column. + * @return The column editor instance. + */ + CE withName(String name); + + /** + * Retrieves the name associated with this column editor. + * + * @return The name of the column. + */ + String ofName(); + + /** + * Sets the data type of the column. + * + * @param typeName The data type name of the column. + * @return The column editor instance. + */ + CE withType(String typeName); + + /** + * Sets the JDBC data type of the column. + * + * @param jdbcType The JDBC data type of the column. + * @return The column editor instance. + */ + CE withJdbcType(JDBCType jdbcType); + + /** + * Sets the EventMesh data type of the column. + * + * @param eventMeshType The EventMesh data type of the column. + * @return The column editor instance. + */ + CE withEventMeshType(EventMeshDataType eventMeshType); + + /** + * Sets the order or position of the column within a table. + * + * @param order The order or position of the column. + * @return The column editor instance. + */ + CE withOrder(int order); + + /** + * Sets the length of the column (if applicable). + * + * @param length The length of the column. + * @return The column editor instance. + */ + CE length(int length); + + /** + * Sets the scale of the column (if applicable). + * + * @param scale The scale of the column. + * @return The column editor instance. + */ + CE scale(Integer scale); + + /** + * Sets whether the column is optional (nullable). + * + * @param optional Indicates whether the column is optional (true) or not (false). + * @return The column editor instance. + */ + CE optional(boolean optional); + + /** + * Sets the comment for the column. + * + * @param comment The comment for the column. + * @return The column editor instance. + */ + CE comment(String comment); + + /** + * Sets the default value expression for the column. + * + * @param defaultValueExpression The default value expression for the column. + * @return The column editor instance. + */ + CE defaultValueExpression(String defaultValueExpression); + + /** + * Sets the default value for the column. + * + * @param value The default value for the column. + * @return The column editor instance. + */ + CE defaultValue(Object value); + + /** + * Sets whether the column is marked as not null. + * + * @param notNull Indicates whether the column is marked as not null (true) or not (false). + * @return The column editor instance. + */ + CE notNull(boolean notNull); + + /** + * Builds and returns the configured column. + * + * @return The configured column. + */ + Col build(); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/DefaultColumn.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/DefaultColumn.java new file mode 100644 index 0000000000..f682ea9438 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/DefaultColumn.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.connector.jdbc.table.catalog; + +import org.apache.eventmesh.connector.jdbc.table.type.EventMeshDataType; + +import java.sql.JDBCType; + +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class DefaultColumn extends Column { + + public DefaultColumn(String name, EventMeshDataType dataType, JDBCType jdbcType, Integer columnLength, Integer decimal, boolean notNull, + String comment, Object defaultValue, String defaultValueExpression) { + super(name, dataType, jdbcType, columnLength, decimal, notNull, comment, defaultValue, defaultValueExpression, 0); + } + + public DefaultColumn(String name, EventMeshDataType dataType, JDBCType jdbcType, Integer columnLength, Integer decimal, boolean notNull, + String comment, Object defaultValue, String defaultValueExpression, int order) { + super(name, dataType, jdbcType, columnLength, decimal, notNull, comment, defaultValue, defaultValueExpression, order); + } + + public static DefaultColumn of( + String name, EventMeshDataType dataType, JDBCType jdbcType, Integer columnLength, Integer decimal, boolean notNull, + String comment, Object defaultValue, String defaultValueExpression) { + return new DefaultColumn(name, dataType, jdbcType, columnLength, decimal, notNull, comment, defaultValue, defaultValueExpression); + } + + public static DefaultColumn of( + String name, EventMeshDataType dataType, JDBCType jdbcType, Integer columnLength, Integer decimal, boolean notNull, + String comment, Object defaultValue, String defaultValueExpression, int order) { + return new DefaultColumn(name, dataType, jdbcType, columnLength, decimal, notNull, comment, defaultValue, defaultValueExpression, order); + } + + /** + * creates a clone of the Column + * + * @return clone of column + */ + @Override + public DefaultColumn clone() { + return DefaultColumn.of(name, dataType, jdbcType, columnLength, decimal, notNull, comment, defaultValue, defaultValueExpression, order); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Options.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Options.java new file mode 100644 index 0000000000..de2429695e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Options.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.connector.jdbc.table.catalog; + +import java.util.HashMap; + +public class Options extends HashMap { + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/PrimaryKey.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/PrimaryKey.java new file mode 100644 index 0000000000..2095b30429 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/PrimaryKey.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.connector.jdbc.table.catalog; + +import java.util.List; + +public class PrimaryKey extends UniqueKey { + + public PrimaryKey() { + } + + public PrimaryKey(String name, List columnNames, String comment) { + super(name, columnNames, comment); + } + + public PrimaryKey(String name, List columnNames) { + super(name, columnNames); + } + + public PrimaryKey(List columnNames) { + super(columnNames); + } + + public PrimaryKey(List columnNames, String comment) { + super(null, columnNames, comment); + } + + /** + * Creates a new PrimaryKey instance with the given name and column names. + * + * @param columnNames The list of column names that make up the primary key. + * @return A new PrimaryKey instance. + */ + public static PrimaryKey of(List columnNames) { + return new PrimaryKey(columnNames); + } + + /** + * Creates a copy of this PrimaryKey instance. + * + * @return A new PrimaryKey instance with the same name and column names. + */ + public PrimaryKey copy() { + return new PrimaryKey(getName(), getColumnNames(), getComment()); + } +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Table.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Table.java new file mode 100644 index 0000000000..34a44eedff --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/Table.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.jdbc.table.catalog; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Table { + + private String name; + + private PrimaryKey primaryKey; + + private List uniqueKeys; + + private String comment; + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableEditor.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableEditor.java new file mode 100644 index 0000000000..18d298ac7b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableEditor.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.connector.jdbc.table.catalog; + +import java.util.List; + +/** + * An interface for editing and configuring properties of a database table schema. + * + * @param The specific type of table editor. + * @param The type of columns in the table. + * @param The type of the resulting table schema. + */ +public interface TableEditor { + + /** + * Sets the unique identifier (ID) of the table. + * + * @param tableId The unique ID of the table. + * @return A reference to the table editor for further configuration. + */ + TE withTableId(TableId tableId); + + /** + * Adds columns to the table. + * + * @param columns The columns to add to the table. + * @return A reference to the table editor for further configuration. + */ + @SuppressWarnings("unchecked") + TE addColumns(Col... columns); + + /** + * Sets a comment or description for the table. + * + * @param comment A comment or description for the table. + * @return A reference to the table editor for further configuration. + */ + TE withComment(String comment); + + /** + * Removes a column from the table. + * + * @param columnName The name of the column to remove. + * @return A reference to the table editor for further configuration. + */ + TE removeColumn(String columnName); + + /** + * Sets the primary key columns for the table. + * + * @param pkColumnNames The names of the columns that form the primary key. + * @param comment A comment or description for the primary key. + * @return A reference to the table editor for further configuration. + */ + TE withPrimaryKeyNames(List pkColumnNames, String comment); + + /** + * Sets the primary key columns for the table. + * + * @param pkColumnNames The names of the columns that form the primary key. + * @return A reference to the table editor for further configuration. + */ + TE withPrimaryKeyNames(String... pkColumnNames); + + /** + * Sets the primary key for the table. + * + * @param primaryKey The primary key definition. + * @return A reference to the table editor for further configuration. + */ + TE withPrimaryKey(PrimaryKey primaryKey); + + /** + * Sets the unique key columns and their names for the table. + * + * @param ukName The name of the unique key constraint. + * @param ukColumnNames The names of the columns that form the unique key. + * @param comment A comment or description for the unique key. + * @return A reference to the table editor for further configuration. + */ + TE withUniqueKeyColumnsNames(String ukName, List ukColumnNames, String comment); + + /** + * Sets the unique key constraints for the table. + * + * @param uniqueKeys The unique key constraints. + * @return A reference to the table editor for further configuration. + */ + TE withUniqueKeys(UniqueKey... uniqueKeys); + + TE withOption(String key, Object value); + + /** + * Builds and returns the table schema with the configured properties. + * + * @return The resulting table schema. + */ + TB build(); +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableId.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableId.java new file mode 100644 index 0000000000..37be433298 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableId.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.connector.jdbc.table.catalog; + +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.Objects; + +import lombok.Getter; +import lombok.Setter; + +/** + * Represents a table identifier with catalog name, schema name and table name. + */ +@Getter +@Setter +public class TableId implements Serializable { + + /** + * The default mapper that converts a TableId to its string representation. + */ + public static final TableIdToStringMapper DEFAULT_TABLEIDTOSTRINGMAPPER = new DefaultTableIdToStringMapper(); + + private String catalogName; + + private String schemaName; + + private String tableName; + + private String id; + + public TableId() { + } + + /** + * Constructs a TableId instance without a TableIdToStringMapper. + * + * @param catalogName the catalog name of the table + * @param schemaName the schema name of the table + * @param tableName the name of the table + */ + public TableId(String catalogName, String schemaName, String tableName) { + this(catalogName, schemaName, tableName, null); + } + + /** + * Constructs a TableId instance without a TableIdToStringMapper. + * + * @param catalogName the catalog name of the table + */ + public TableId(String catalogName) { + this(catalogName, null, null, null); + } + + /** + * Constructs a TableId instance with a TableIdToStringMapper. If the mapper is null, the default mapper will be used. + * + * @param catalogName the catalog name of the table + * @param schemaName the schema name of the table + * @param tableName the name of the table + * @param mapper the mapper that converts a TableId to its string representation + */ + public TableId(String catalogName, String schemaName, String tableName, TableIdToStringMapper mapper) { + this.catalogName = catalogName; + this.schemaName = schemaName; + this.tableName = tableName; + this.id = mapper == null ? DEFAULT_TABLEIDTOSTRINGMAPPER.toString(this) : mapper.toString(this); + + } + + @Override + public String toString() { + return id == null ? DEFAULT_TABLEIDTOSTRINGMAPPER.toString(this) : id; + } + + /** + * Returns the string representation of the TableId, which is the same as calling toString(). + * + * @return the string representation of the TableId + */ + public String tablePath() { + return id; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof TableId)) { + return false; + } + TableId tableId = (TableId) o; + return Objects.equals(getCatalogName(), tableId.getCatalogName()) && Objects.equals(getSchemaName(), tableId.getSchemaName()) + && Objects.equals(getTableName(), tableId.getTableName()); + } + + @Override + public int hashCode() { + return Objects.hash(getCatalogName(), getSchemaName(), getTableName()); + } + + /** + * A functional interface that converts a TableId to its string representation. + */ + @FunctionalInterface + public interface TableIdToStringMapper { + + String toString(TableId tableId); + } + + /** + * Returns the string representation of a TableId. If catalog or schema is null or empty, they will be excluded from the string. + * + * @param catalog the catalog name of the table + * @param schema the schema name of the table + * @param table the name of the table + * @return the string representation of the TableId + */ + private static String tableId(String catalog, String schema, String table) { + StringBuilder tableId = new StringBuilder(); + if (StringUtils.isNotBlank(catalog)) { + tableId.append(catalog).append("."); + } + if (StringUtils.isNotBlank(schema)) { + tableId.append(schema).append("."); + } + if (StringUtils.isNotBlank(table)) { + tableId.append(table).append("."); + } + if (tableId.length() == 0) { + return null; + } + return tableId.substring(0, tableId.length() - 1); + } + + /** + * The default mapper that converts a TableId to its string representation. + */ + private static class DefaultTableIdToStringMapper implements TableIdToStringMapper { + + public String toString(TableId tableId) { + return tableId(tableId.getCatalogName(), tableId.getSchemaName(), tableId.getTableName()); + } + } + + public TableId copy() { + return new TableId(this.catalogName, this.schemaName, this.tableName); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableSchema.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableSchema.java new file mode 100644 index 0000000000..3eadd78d56 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableSchema.java @@ -0,0 +1,206 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.table.catalog; + +import org.apache.eventmesh.connector.jdbc.table.catalog.mysql.MysqlColumn; +import org.apache.eventmesh.connector.jdbc.table.catalog.mysql.MysqlTableSchema; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class TableSchema implements Serializable { + + private TableId tableId = new TableId(); + + /** + * A map of column names to their respective column objects. + */ + private Map columnMap; + + /** + * A list of columns in the table. + */ + private List columns; + + private Map orderColumnMap; + + /** + * The primary key of the table. + */ + private PrimaryKey primaryKey; + + private List uniqueKeys; + + private String comment; + + public TableSchema(TableId tableId, Map columnMap, List columns, + Map orderColumnMap, PrimaryKey primaryKey, List uniqueKeys, String comment) { + this.tableId = tableId; + this.columnMap = columnMap; + this.columns = columns; + this.orderColumnMap = orderColumnMap; + this.primaryKey = primaryKey; + this.uniqueKeys = uniqueKeys; + this.comment = comment; + } + + public TableSchema(String name) { + this.tableId.setTableName(name); + } + + public TableSchema(TableId tableId) { + this.tableId = tableId; + } + + public String getSimpleName() { + return this.tableId.getTableName(); + } + + public static TableSchemaBuilder newTableSchemaBuilder() { + return new TableSchemaBuilder(); + } + + public static class TableSchemaBuilder { + + private TableId tableId; + private Map columnMap; + private Map orderColumnMap; + private List columns; + private PrimaryKey primaryKey; + private List uniqueKeys; + private String comment; + + public TableSchemaBuilder() { + + } + + public TableSchemaBuilder withTableId(TableId tableId) { + this.tableId = tableId; + return this; + } + + public TableSchemaBuilder withColumns(Map columnMap) { + this.columnMap = columnMap; + return this; + } + + public TableSchemaBuilder withColumns(List columns) { + this.columns = columns; + return this; + } + + public TableSchemaBuilder withPrimaryKey(PrimaryKey primaryKey) { + this.primaryKey = primaryKey; + return this; + } + + public TableSchemaBuilder withUniqueKeys(List uniqueKeys) { + this.uniqueKeys = uniqueKeys; + return this; + } + + public TableSchemaBuilder withComment(String comment) { + this.comment = comment; + return this; + } + + public TableSchema build() { + return new TableSchema(tableId, columnMap, columns, orderColumnMap, primaryKey, uniqueKeys, comment); + } + + } + + public static MysqlTableSchemaBuilder newMysqlTableSchemaBuilder() { + return new MysqlTableSchemaBuilder(); + } + + public static class MysqlTableSchemaBuilder { + + private TableId tableId = new TableId(); + private Map columnMap; + private Map orderColumnMap; + private List columns; + private PrimaryKey primaryKey; + private List uniqueKeys; + private String comment; + private Options tableOptions = new Options(); + + public MysqlTableSchemaBuilder() { + + } + + public MysqlTableSchemaBuilder withName(String name) { + this.tableId.setTableName(name); + return this; + } + + public MysqlTableSchemaBuilder withTableId(TableId tableId) { + this.tableId = tableId; + return this; + } + + public MysqlTableSchemaBuilder withColumns(List columns) { + this.columns = columns; + this.columnMap = Optional.ofNullable(columns).orElse(new ArrayList<>(0)).stream() + .collect(Collectors.toMap(MysqlColumn::getName, Function.identity())); + this.orderColumnMap = Optional.ofNullable(columns).orElse(new ArrayList<>(0)).stream() + .collect(Collectors.toMap(MysqlColumn::getOrder, Function.identity())); + return this; + } + + public MysqlTableSchemaBuilder withPrimaryKey(PrimaryKey primaryKey) { + this.primaryKey = primaryKey; + return this; + } + + public MysqlTableSchemaBuilder withUniqueKeys(List uniqueKeys) { + this.uniqueKeys = uniqueKeys; + return this; + } + + public MysqlTableSchemaBuilder withComment(String comment) { + this.comment = comment; + return this; + } + + public MysqlTableSchemaBuilder withOption(String key, Object value) { + this.tableOptions.put(key, value); + return this; + } + + public MysqlTableSchemaBuilder withOptions(Options options) { + this.tableOptions.putAll(options); + return this; + } + + public MysqlTableSchema build() { + return new MysqlTableSchema(tableId, columnMap, columns, orderColumnMap, primaryKey, uniqueKeys, comment, tableOptions); + } + + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/UniqueKey.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/UniqueKey.java new file mode 100644 index 0000000000..f44ed561f4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/UniqueKey.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.jdbc.table.catalog; + +import java.io.Serializable; +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +/** + * Represents a unique key constraint for a database table. + *

A unique key ensures that the values in specified columns are unique across all rows in the table.

+ */ +@Setter +@Getter +public class UniqueKey implements Serializable { + + // The name of the unique key, if specified. + private String name; + + // The list of column names that make up the unique/primary key. + private List columnNames; + + // An optional comment or description for the unique/primary key. + private String comment; + + public UniqueKey() { + } + + public UniqueKey(String name, List columnNames, String comment) { + this.name = name; + this.columnNames = columnNames; + this.comment = comment; + } + + public UniqueKey(String name, List columnNames) { + this.name = name; + this.columnNames = columnNames; + } + + public UniqueKey(List columnNames) { + this.columnNames = columnNames; + } + + public UniqueKey copy() { + return new UniqueKey(name, columnNames, comment); + } + + public void addColumnNames(String... columnNames) { + if (columnNames != null && columnNames.length > 0) { + for (String columnName : columnNames) { + this.columnNames.add(columnName); + } + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlColumn.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlColumn.java new file mode 100644 index 0000000000..c0440a4d14 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlColumn.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.connector.jdbc.table.catalog.mysql; + +import org.apache.eventmesh.connector.jdbc.table.catalog.Column; +import org.apache.eventmesh.connector.jdbc.table.type.EventMeshDataType; + +import java.sql.JDBCType; + +/** + * Represents a MySQL column in a database table. + */ +public class MysqlColumn extends Column { + + private boolean autoIncremented; + + private boolean generated; + + private String collationName; + + public MysqlColumn(String name, EventMeshDataType dataType, JDBCType jdbcType, Integer columnLength, Integer decimal, boolean notNull, + String comment, Object defaultValue, String defaultValueExpression, boolean autoIncremented, boolean generated, String collationName) { + super(name, dataType, jdbcType, columnLength, decimal, notNull, comment, defaultValue, defaultValueExpression, 0); + this.autoIncremented = autoIncremented; + this.generated = generated; + this.collationName = collationName; + } + + public MysqlColumn(String name, EventMeshDataType dataType, JDBCType jdbcType, Integer columnLength, Integer decimal, boolean notNull, + String comment, Object defaultValue, String defaultValueExpression, boolean autoIncremented, boolean generated, String collationName, + int order) { + super(name, dataType, jdbcType, columnLength, decimal, notNull, comment, defaultValue, defaultValueExpression, order); + this.autoIncremented = autoIncremented; + this.generated = generated; + this.collationName = collationName; + } + + public MysqlColumn() { + + } + + public static MysqlColumn of( + String name, EventMeshDataType dataType, JDBCType jdbcType, Integer columnLength, Integer decimal, boolean notNull, + String comment, Object defaultValue, String defaultValueExpression, boolean autoIncremented, boolean generated, String collationName) { + return new MysqlColumn(name, dataType, jdbcType, columnLength, decimal, notNull, comment, defaultValue, defaultValueExpression, + autoIncremented, generated, collationName); + } + + public static MysqlColumn of( + String name, EventMeshDataType dataType, JDBCType jdbcType, Integer columnLength, Integer decimal, boolean notNull, String comment, + Object defaultValue, String defaultValueExpression, boolean autoIncremented, boolean generated, String collationName, int order) { + return new MysqlColumn(name, dataType, jdbcType, columnLength, decimal, notNull, comment, defaultValue, defaultValueExpression, + autoIncremented, generated, collationName, order); + } + + /** + * creates a clone of the Column + * + * @return clone of column + */ + @Override + public MysqlColumn clone() { + return null; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlColumnEditor.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlColumnEditor.java new file mode 100644 index 0000000000..cea5ea9ceb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlColumnEditor.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.jdbc.table.catalog.mysql; + +import org.apache.eventmesh.connector.jdbc.table.catalog.ColumnEditor; + +/** + * Interface for editing MySQL column properties. + */ +public interface MysqlColumnEditor extends ColumnEditor { + + /** + * Creates a new MySQL column editor with the specified name. + * + * @param name The name of the column. + * @return A new MySQL column editor instance. + */ + static MysqlColumnEditor ofEditor(String name) { + return new MysqlColumnEditorImpl(name); + } + + /** + * Creates a new MySQL column editor without specifying a name. + * + * @return A new MySQL column editor instance. + */ + static MysqlColumnEditor ofEditor() { + return new MysqlColumnEditorImpl(); + } + + /** + * Sets whether the column is auto-incremented. + * + * @param autoIncremented Whether the column is auto-incremented. + * @return The ColumnEditor instance. + */ + MysqlColumnEditor autoIncremented(boolean autoIncremented); + + /** + * Sets whether the column is generated. + * + * @param generated Whether the column is generated. + * @return The ColumnEditor instance. + */ + MysqlColumnEditor generated(boolean generated); + + /** + * Sets the collation (character set) for the column. + * + * @param collationName The name of the collation to set. + * @return The column editor with the collation set. + */ + MysqlColumnEditor collate(String collationName); + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlColumnEditorImpl.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlColumnEditorImpl.java new file mode 100644 index 0000000000..c7b7648af2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlColumnEditorImpl.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.jdbc.table.catalog.mysql; + +import org.apache.eventmesh.connector.jdbc.table.catalog.AbstractColumnEditorImpl; + +public class MysqlColumnEditorImpl extends AbstractColumnEditorImpl implements MysqlColumnEditor { + + private boolean autoIncremented; + + private boolean generated; + + private String collationName; + + public MysqlColumnEditorImpl(String name) { + super(name); + } + + public MysqlColumnEditorImpl() { + } + + /** + * Sets whether the column is auto-incremented. + * + * @param autoIncremented Whether the column is auto-incremented. + * @return The ColumnEditor instance. + */ + @Override + public MysqlColumnEditor autoIncremented(boolean autoIncremented) { + this.autoIncremented = autoIncremented; + return this; + } + + /** + * Sets whether the column is generated. + * + * @param generated Whether the column is generated. + * @return The ColumnEditor instance. + */ + @Override + public MysqlColumnEditor generated(boolean generated) { + this.generated = generated; + return this; + } + + /** + * Sets the collation (character set) for the column. + * + * @param collationName The name of the collation to set. + * @return The column editor with the collation set. + */ + @Override + public MysqlColumnEditor collate(String collationName) { + this.collationName = collationName; + return this; + } + + /** + * Builds and returns the configured column. + * + * @return The configured column. + */ + @Override + public MysqlColumn build() { + return MysqlColumn.of(ofName(), ofEventMeshDataType(), ofJdbcType(), ofColumnLength(), ofScale(), isNotNull(), ofComment(), ofDefaultValue(), + ofDefaultValueExpression(), autoIncremented, generated, collationName, ofOrder()); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableEditor.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableEditor.java new file mode 100644 index 0000000000..a62f7b7526 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableEditor.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.connector.jdbc.table.catalog.mysql; + +import org.apache.eventmesh.connector.jdbc.table.catalog.TableEditor; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +/** + * Interface for editing MySQL table schemas. + */ +public interface MysqlTableEditor extends TableEditor { + + /** + * Create a new instance of MysqlTableEditor for a specific table identified by its TableId. + * + * @param tableId The unique identifier for the table. + * @return A new MysqlTableEditor instance. + */ + static MysqlTableEditor ofCatalogTableEditor(TableId tableId) { + return new MysqlTableEditorImpl(tableId); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableEditorImpl.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableEditorImpl.java new file mode 100644 index 0000000000..852349b5bc --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableEditorImpl.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.connector.jdbc.table.catalog.mysql; + +import org.apache.eventmesh.connector.jdbc.table.catalog.AbstractTableEditorImpl; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableSchema; + +import java.util.ArrayList; + +public class MysqlTableEditorImpl extends AbstractTableEditorImpl implements MysqlTableEditor { + + public MysqlTableEditorImpl(TableId tableId) { + super(tableId); + } + + /** + * Builds and returns the table schema with the configured properties. + * + * @return The resulting table schema. + */ + @Override + public MysqlTableSchema build() { + return TableSchema.newMysqlTableSchemaBuilder() + .withTableId(ofTableId()) + .withColumns(new ArrayList<>(ofColumns().values())) + .withPrimaryKey(ofPrimaryKey()) + .withUniqueKeys(ofUniqueKeys()) + .withComment(ofComment()) + .withOptions(ofOptions()) + .build(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableOptions.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableOptions.java new file mode 100644 index 0000000000..d0a3c1108d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableOptions.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.jdbc.table.catalog.mysql; + +public class MysqlTableOptions { + + public static String ENGINE = "ENGINE"; + + public static String AUTO_INCREMENT = "AUTO_INCREMENT"; + + public static String CHARSET = "CHARSET"; + + public static String COLLATE = "COLLATE"; +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableSchema.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableSchema.java new file mode 100644 index 0000000000..c26ca5c3ce --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/catalog/mysql/MysqlTableSchema.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.connector.jdbc.table.catalog.mysql; + +import org.apache.eventmesh.connector.jdbc.table.catalog.Options; +import org.apache.eventmesh.connector.jdbc.table.catalog.PrimaryKey; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; +import org.apache.eventmesh.connector.jdbc.table.catalog.TableSchema; +import org.apache.eventmesh.connector.jdbc.table.catalog.UniqueKey; + +import java.util.List; +import java.util.Map; + +public class MysqlTableSchema extends TableSchema { + + private Options tableOptions; + + public MysqlTableSchema(TableId tableId, Map columnMap, List columns, Map orderColumnMap, + PrimaryKey primaryKey, List uniqueKeys, String comment, Options tableOptions) { + super(tableId, columnMap, columns, orderColumnMap, primaryKey, uniqueKeys, comment); + this.tableOptions = tableOptions; + } + + public MysqlTableSchema() { + } + + public MysqlTableSchema(String name) { + super(name); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/CalendarType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/CalendarType.java new file mode 100644 index 0000000000..788b85ecd7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/CalendarType.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.jdbc.table.type; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.Temporal; +import java.util.Objects; + +public class CalendarType implements EventMeshDataType { + + // Constants for LocalDate, LocalTime, and LocalDateTime types + public static final CalendarType LOCAL_DATE_TYPE = new CalendarType<>(LocalDate.class, SQLType.DATE); + + public static final CalendarType LOCAL_TIME_TYPE = new CalendarType<>(LocalTime.class, SQLType.TIME); + + public static final CalendarType LOCAL_DATE_TIME_TYPE = new CalendarType<>(LocalDateTime.class, SQLType.TIMESTAMP); + + private final Class typeClass; + private final SQLType sqlType; + + private CalendarType(Class typeClass, SQLType sqlType) { + this.typeClass = typeClass; + this.sqlType = sqlType; + } + + /** + * Returns the type class of the data. + * + * @return the type class of the data. + */ + @Override + public Class getTypeClass() { + return typeClass; + } + + /** + * Returns the SQL type of the data. + * + * @return the SQL type of the data. + */ + @Override + public SQLType getSQLType() { + return sqlType; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof CalendarType)) { + return false; + } + CalendarType that = (CalendarType) o; + return Objects.equals(getTypeClass(), that.getTypeClass()) && sqlType == that.sqlType; + } + + @Override + public int hashCode() { + return Objects.hash(getTypeClass(), sqlType); + } + + @Override + public String toString() { + return typeClass.getName(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/DecimalType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/DecimalType.java new file mode 100644 index 0000000000..44fed4a667 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/DecimalType.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.connector.jdbc.table.type; + +import java.math.BigDecimal; +import java.util.Objects; + +import lombok.Getter; + +public class DecimalType extends PrimitiveType { + + @Getter + private final int scale; + + @Getter + private final int precision; + + public DecimalType(int scale, int precision) { + super(BigDecimal.class, SQLType.DECIMAL); + this.precision = precision; + this.scale = scale; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof DecimalType)) { + return false; + } + if (!super.equals(o)) { + return false; + } + DecimalType that = (DecimalType) o; + return precision == that.precision && scale == that.scale; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), precision, scale); + } + + @Override + public String toString() { + return getTypeClass().getName(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EventMeshDataType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EventMeshDataType.java new file mode 100644 index 0000000000..07da72bea7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EventMeshDataType.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.connector.jdbc.table.type; + +/** + * Defines Event Mesh data type with methods to get the type class and SQL type of the data. + */ +public interface EventMeshDataType { + + /** + * Gets the type class of the data. + * + * @return the type class of the data. + */ + Class getTypeClass(); + + /** + * Gets the SQL type of the data. + * + * @return the SQL type of the data. + */ + SQLType getSQLType(); + + /** + * Gets the name of the data type. + * + * @return The name of the data type. + */ + default String getName() { + return EventMeshTypeNameConverter.ofName(this); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EventMeshRow.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EventMeshRow.java new file mode 100644 index 0000000000..81c24a3a08 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EventMeshRow.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.connector.jdbc.table.type; + +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import lombok.Getter; +import lombok.Setter; + +/** + * Represents a row in an event mesh. + */ +@Getter +@Setter +public class EventMeshRow implements Serializable { + + /** + * The mode for handling the row (e.g. INSERT, UPDATE, DELETE) {@link RowHandleMode} + */ + private RowHandleMode mode = RowHandleMode.INSERT; + + /** + * The ID of the table that the row belongs to + */ + private TableId tableId; + + /** + * The values of the fields in the row + */ + private final Object[] fieldValues; + + /** + * Any additional metadata associated with the row + */ + private Map ext = new HashMap<>(); + + public EventMeshRow(int fieldNum) { + this.fieldValues = new Object[fieldNum]; + } + + public EventMeshRow(int fieldNum, TableId tableId) { + this.tableId = tableId; + this.fieldValues = new Object[fieldNum]; + } + + public EventMeshRow(RowHandleMode mode, int fieldNum, TableId tableId) { + this.mode = mode; + this.tableId = tableId; + this.fieldValues = new Object[fieldNum]; + } + + /** + * Sets the values of the fields in the row. + * + * @param fieldValues the new field values + * @throws NullPointerException if fieldValues is null + * @throws IllegalArgumentException if fieldValues has a different length than the existing field values + */ + public void setFieldValues(Object[] fieldValues) { + Objects.requireNonNull(fieldValues, "Parameter fields can not be null"); + if (this.fieldValues.length != fieldValues.length) { + throw new IllegalArgumentException(); + } + System.arraycopy(fieldValues, 0, this.fieldValues, 0, this.fieldValues.length); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EventMeshTypeNameConverter.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EventMeshTypeNameConverter.java new file mode 100644 index 0000000000..181e735a91 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EventMeshTypeNameConverter.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.connector.jdbc.table.type; + +import java.util.HashMap; +import java.util.Map; + +public final class EventMeshTypeNameConverter { + + private static Map, String> PRIMITIVE_TYPE_MAP = new HashMap<>(32); + + static { + PRIMITIVE_TYPE_MAP.put(PrimitiveType.STRING_TYPE, "string"); + PRIMITIVE_TYPE_MAP.put(PrimitiveType.BOOLEAN_TYPE, "bool"); + PRIMITIVE_TYPE_MAP.put(PrimitiveType.BYTE_TYPE, "byte"); + PRIMITIVE_TYPE_MAP.put(PrimitiveType.SHORT_TYPE, "short"); + PRIMITIVE_TYPE_MAP.put(PrimitiveType.INT_TYPE, "int"); + PRIMITIVE_TYPE_MAP.put(PrimitiveType.LONG_TYPE, "long"); + PRIMITIVE_TYPE_MAP.put(PrimitiveType.FLOAT_TYPE, "float"); + PRIMITIVE_TYPE_MAP.put(PrimitiveType.DOUBLE_TYPE, "double"); + PRIMITIVE_TYPE_MAP.put(PrimitiveType.VOID_TYPE, "void"); + PRIMITIVE_TYPE_MAP.put(CalendarType.LOCAL_DATE_TYPE, "LocalDate"); + PRIMITIVE_TYPE_MAP.put(CalendarType.LOCAL_TIME_TYPE, "LocalTime"); + PRIMITIVE_TYPE_MAP.put(CalendarType.LOCAL_DATE_TIME_TYPE, "LocalDateTime"); + PRIMITIVE_TYPE_MAP.put(PrimitiveByteArrayType.BYTES_TYPE, "bytes"); + + PRIMITIVE_TYPE_MAP.put(PrimitiveArrayType.STRING_ARRAY_TYPE, "string-array"); + PRIMITIVE_TYPE_MAP.put(PrimitiveArrayType.BOOLEAN_ARRAY_TYPE, "bool-array"); + PRIMITIVE_TYPE_MAP.put(PrimitiveArrayType.BYTE_ARRAY_TYPE, "byte-array"); + PRIMITIVE_TYPE_MAP.put(PrimitiveArrayType.SHORT_ARRAY_TYPE, "short-array"); + PRIMITIVE_TYPE_MAP.put(PrimitiveArrayType.INT_ARRAY_TYPE, "int-array"); + PRIMITIVE_TYPE_MAP.put(PrimitiveArrayType.LONG_ARRAY_TYPE, "long-array"); + PRIMITIVE_TYPE_MAP.put(PrimitiveArrayType.FLOAT_ARRAY_TYPE, "float-array"); + PRIMITIVE_TYPE_MAP.put(PrimitiveArrayType.DOUBLE_ARRAY_TYPE, "double-array"); + } + + public static String ofName(EventMeshDataType type) { + String typeName = PRIMITIVE_TYPE_MAP.get(type); + if (typeName == null && (type instanceof DecimalType)) { + DecimalType decimalType = (DecimalType) type; + return String.format("decimal(%s,%s)", decimalType.getScale(), decimalType.getPrecision()); + } + return typeName; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EvetMeshRowType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EvetMeshRowType.java new file mode 100644 index 0000000000..ece432c28f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/EvetMeshRowType.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.connector.jdbc.table.type; + +import java.util.List; + +public class EvetMeshRowType implements EventMeshDataType { + + private List>> fields; + + public EvetMeshRowType(List>> fields) { + this.fields = fields; + } + + /** + * Returns the type class of the data. + * + * @return the type class of the data. + */ + @Override + public Class getTypeClass() { + return EventMeshRow.class; + } + + /** + * Returns the SQL type of the data. + * + * @return the SQL type of the data. + */ + @Override + public SQLType getSQLType() { + return SQLType.ROW; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/MapType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/MapType.java new file mode 100644 index 0000000000..5e33d818bf --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/MapType.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.jdbc.table.type; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public class MapType implements EventMeshDataType> { + + private static final List SUPPORTED_KEY_TYPES = + Arrays.asList( + SQLType.NULL, + SQLType.BOOLEAN, + SQLType.TINYINT, + SQLType.SMALLINT, + SQLType.INTEGER, + SQLType.BIGINT, + SQLType.DATE, + SQLType.TIME, + SQLType.TIMESTAMP, + SQLType.FLOAT, + SQLType.DOUBLE, + SQLType.STRING, + SQLType.DECIMAL); + + private final EventMeshDataType keyType; + + private final EventMeshDataType valueType; + + public MapType(EventMeshDataType keyType, EventMeshDataType valueType) { + Objects.requireNonNull(keyType, "The key type is required."); + Objects.requireNonNull(valueType, "The value type is required."); + + if (!SUPPORTED_KEY_TYPES.contains(keyType.getSQLType())) { + throw new IllegalArgumentException(String.format("Not support type: %s", keyType.getSQLType())); + } + + this.keyType = keyType; + this.valueType = valueType; + } + + /** + * Returns the type class of the data. + * + * @return the type class of the data. + */ + @SuppressWarnings("unchecked") + @Override + public Class> getTypeClass() { + return (Class>) (Class) Map.class; + } + + /** + * Returns the SQL type of the data. + * + * @return the SQL type of the data. + */ + @Override + public SQLType getSQLType() { + return SQLType.MAP; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof MapType)) { + return false; + } + MapType mapType = (MapType) o; + return Objects.equals(keyType, mapType.keyType) && Objects.equals(valueType, mapType.valueType); + } + + @Override + public int hashCode() { + return Objects.hash(keyType, valueType); + } + + public EventMeshDataType keyType() { + return this.keyType; + } + + public EventMeshDataType valueType() { + return this.valueType; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/Pair.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/Pair.java new file mode 100644 index 0000000000..e5f0dd72ae --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/Pair.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.jdbc.table.type; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Pair { + + private Left left; + + private Right right; + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/PrimitiveArrayType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/PrimitiveArrayType.java new file mode 100644 index 0000000000..d7f9abeb00 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/PrimitiveArrayType.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.jdbc.table.type; + +import java.util.Objects; + +public class PrimitiveArrayType implements EventMeshDataType { + + @SuppressWarnings("unchecked") + public static final PrimitiveArrayType STRING_ARRAY_TYPE = new PrimitiveArrayType(String[].class, PrimitiveType.STRING_TYPE); + + @SuppressWarnings("unchecked") + public static final PrimitiveArrayType BOOLEAN_ARRAY_TYPE = new PrimitiveArrayType(Boolean[].class, + PrimitiveType.BOOLEAN_TYPE); + + @SuppressWarnings("unchecked") + public static final PrimitiveArrayType BYTE_ARRAY_TYPE = new PrimitiveArrayType(Byte[].class, PrimitiveType.BYTE_TYPE); + + @SuppressWarnings("unchecked") + public static final PrimitiveArrayType SHORT_ARRAY_TYPE = new PrimitiveArrayType(Short[].class, PrimitiveType.SHORT_TYPE); + + @SuppressWarnings("unchecked") + public static final PrimitiveArrayType INT_ARRAY_TYPE = new PrimitiveArrayType(Integer[].class, PrimitiveType.INT_TYPE); + + @SuppressWarnings("unchecked") + public static final PrimitiveArrayType LONG_ARRAY_TYPE = new PrimitiveArrayType(Long[].class, PrimitiveType.LONG_TYPE); + + @SuppressWarnings("unchecked") + public static final PrimitiveArrayType FLOAT_ARRAY_TYPE = new PrimitiveArrayType(Float[].class, PrimitiveType.FLOAT_TYPE); + + @SuppressWarnings("unchecked") + public static final PrimitiveArrayType DOUBLE_ARRAY_TYPE = new PrimitiveArrayType(Double[].class, PrimitiveType.DOUBLE_TYPE); + + private final Class typeClass; + + private final PrimitiveType sqlType; + + private PrimitiveArrayType(Class arrayClass, PrimitiveType elementType) { + this.typeClass = arrayClass; + this.sqlType = elementType; + } + + /** + * Returns the type class of the data. + * + * @return the type class of the data. + */ + @Override + public Class getTypeClass() { + return typeClass; + } + + /** + * Returns the SQL type of the data. + * + * @return the SQL type of the data. + */ + @Override + public SQLType getSQLType() { + return SQLType.ARRAY; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof PrimitiveArrayType)) { + return false; + } + PrimitiveArrayType that = (PrimitiveArrayType) o; + return Objects.equals(getTypeClass(), that.getTypeClass()) && Objects.equals(sqlType, that.sqlType); + } + + @Override + public int hashCode() { + return Objects.hash(getTypeClass(), sqlType); + } + + @Override + public String toString() { + return typeClass.getName(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/PrimitiveByteArrayType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/PrimitiveByteArrayType.java new file mode 100644 index 0000000000..eb4ee47bbf --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/PrimitiveByteArrayType.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.connector.jdbc.table.type; + +public class PrimitiveByteArrayType implements EventMeshDataType { + + public static final PrimitiveByteArrayType BYTES_TYPE = new PrimitiveByteArrayType(); + + private PrimitiveByteArrayType() { + + } + + /** + * Returns the type class of the data. + * + * @return the type class of the data. + */ + @Override + public Class getTypeClass() { + return byte[].class; + } + + /** + * Returns the SQL type of the data. + * + * @return the SQL type of the data. + */ + @Override + public SQLType getSQLType() { + return SQLType.BINARY; + } + + @Override + public int hashCode() { + return byte[].class.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + return obj instanceof PrimitiveByteArrayType; + } + + @Override + public String toString() { + return byte[].class.getName(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/PrimitiveType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/PrimitiveType.java new file mode 100644 index 0000000000..d6e8bdd514 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/PrimitiveType.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.jdbc.table.type; + +import java.util.Objects; + +public class PrimitiveType implements EventMeshDataType { + + public static final PrimitiveType STRING_TYPE = new PrimitiveType<>(String.class, SQLType.STRING); + public static final PrimitiveType BOOLEAN_TYPE = new PrimitiveType<>(Boolean.class, SQLType.BOOLEAN); + public static final PrimitiveType BYTE_TYPE = new PrimitiveType<>(Byte.class, SQLType.TINYINT); + public static final PrimitiveType SHORT_TYPE = new PrimitiveType<>(Short.class, SQLType.SMALLINT); + public static final PrimitiveType INT_TYPE = new PrimitiveType<>(Integer.class, SQLType.INTEGER); + public static final PrimitiveType LONG_TYPE = new PrimitiveType<>(Long.class, SQLType.BIGINT); + public static final PrimitiveType FLOAT_TYPE = new PrimitiveType<>(Float.class, SQLType.FLOAT); + public static final PrimitiveType DOUBLE_TYPE = new PrimitiveType<>(Double.class, SQLType.DOUBLE); + public static final PrimitiveType VOID_TYPE = new PrimitiveType<>(Void.class, SQLType.NULL); + + private final Class typeClass; + + private final SQLType sqlType; + + public PrimitiveType(Class typeClass, SQLType sqlType) { + this.typeClass = typeClass; + this.sqlType = sqlType; + } + + /** + * Returns the type class of the data. + * + * @return the type class of the data. + */ + @Override + public Class getTypeClass() { + return typeClass; + } + + /** + * Returns the SQL type of the data. + * + * @return the SQL type of the data. + */ + @Override + public SQLType getSQLType() { + return sqlType; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof PrimitiveType)) { + return false; + } + PrimitiveType that = (PrimitiveType) o; + return Objects.equals(getTypeClass(), that.getTypeClass()) && sqlType == that.sqlType; + } + + @Override + public int hashCode() { + return Objects.hash(getTypeClass(), sqlType); + } + + @Override + public String toString() { + return typeClass.getName(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/RowHandleMode.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/RowHandleMode.java new file mode 100644 index 0000000000..d83cd48a31 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/RowHandleMode.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.connector.jdbc.table.type; + +/** + * An enum representing the different modes in which a row can be handled. + */ +public enum RowHandleMode { + + INSERT("+I", (byte) 1), + UPDATE_BEFORE("-UB", (byte) 2), + UPDATE_AFTER("+UA", (byte) 3), + DELETE("-D", (byte) 1), + ; + + private final String shortCut; + + private final byte value; + + /** + * Constructor for RowHandleMode. + * + * @param shortCut a string representing the shorthand for the row handle mode. + * @param value a byte representing the value of the row handle mode. + */ + RowHandleMode(String shortCut, byte value) { + this.shortCut = shortCut; + this.value = value; + } + + /** + * Returns the shorthand for the row handle mode. + * + * @return a string representing the shorthand for the row handle mode. + */ + public String toShortCut() { + return shortCut; + } + + /** + * Returns the value of the row handle mode. + * + * @return a byte representing the value of the row handle mode. + */ + public byte toValue() { + return value; + } + + /** + * Returns the row handle mode corresponding to the given byte value. + * + * @param value a byte representing the value of the row handle mode. + * @return the row handle mode corresponding to the given byte value. + * @throws UnsupportedOperationException if the byte value is not supported. + */ + public static RowHandleMode fromByteValue(byte value) { + switch (value) { + case 0: + return INSERT; + case 1: + return UPDATE_BEFORE; + case 2: + return UPDATE_AFTER; + case 3: + return DELETE; + default: + throw new UnsupportedOperationException( + "Unsupported byte value '" + value + "' for row handle mode."); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/SQLType.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/SQLType.java new file mode 100644 index 0000000000..203ceb84bb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/table/type/SQLType.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.connector.jdbc.table.type; + +/** + * see {@link java.sql.SQLType} + */ +public enum SQLType { + + /** + * Identifies the generic SQL type {@code TINYINT}. + */ + TINYINT, + /** + * Identifies the generic SQL type {@code SMALLINT}. + */ + SMALLINT, + /** + * Identifies the generic SQL type {@code INTEGER}. + */ + INTEGER, + /** + * Identifies the generic SQL type {@code BIGINT}. + */ + BIGINT, + /** + * Identifies the generic SQL type {@code FLOAT}. + */ + FLOAT, + + /** + * Identifies the generic SQL type {@code DOUBLE}. + */ + DOUBLE, + + /** + * Identifies the generic SQL type {@code DECIMAL}. + */ + DECIMAL, + + /** + * Identifies the generic SQL type {@code DATE}. + */ + DATE, + /** + * Identifies the generic SQL type {@code TIME}. + */ + TIME, + /** + * Identifies the generic SQL type {@code TIMESTAMP}. + */ + TIMESTAMP, + /** + * Identifies the generic SQL type {@code BINARY}. + */ + BINARY, + + /** + * Identifies the generic SQL value {@code NULL}. + */ + NULL, + + /** + * Identifies the generic SQL type {@code ARRAY}. + */ + ARRAY, + + /** + * Identifies the generic SQL type {@code BOOLEAN}. + */ + BOOLEAN, + + /** + * EventMesh generic SQL type + */ + ROW, + + MAP, + + STRING +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/utils/Antlr4Utils.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/utils/Antlr4Utils.java new file mode 100644 index 0000000000..6cee8cd01e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/utils/Antlr4Utils.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.connector.jdbc.utils; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.misc.Interval; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class Antlr4Utils { + + public static String getText(ParserRuleContext ctx) { + return getText(ctx, ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex()); + } + + public static String getText(ParserRuleContext ctx, int start, int stop) { + Interval interval = new Interval(start, stop); + return ctx.getStart().getInputStream().getText(interval); + } +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/utils/JdbcStringUtils.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/utils/JdbcStringUtils.java new file mode 100644 index 0000000000..98fb897a6c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/utils/JdbcStringUtils.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.connector.jdbc.utils; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class JdbcStringUtils { + + public static boolean isWrapped(String possiblyWrapped) { + if (possiblyWrapped.length() < 2) { + return false; + } + if (possiblyWrapped.startsWith("`") && possiblyWrapped.endsWith("`")) { + return true; + } + if (possiblyWrapped.startsWith("'") && possiblyWrapped.endsWith("'")) { + return true; + } + if (possiblyWrapped.startsWith("\"") && possiblyWrapped.endsWith("\"")) { + return true; + } + return false; + } + + public static boolean isWrapped(char c) { + return c == '\'' || c == '"' || c == '`'; + } + + public static String withoutWrapper(String possiblyWrapped) { + return isWrapped(possiblyWrapped) ? possiblyWrapped.substring(1, possiblyWrapped.length() - 1) : possiblyWrapped; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/utils/MysqlUtils.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/utils/MysqlUtils.java new file mode 100644 index 0000000000..c272b1b879 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/java/org/apache/eventmesh/connector/jdbc/utils/MysqlUtils.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.connector.jdbc.utils; + +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +public class MysqlUtils { + + private MysqlUtils() { + + } + + public static String wrapper(TableId tableId) { + return wrapper(tableId.toString()); + } + + public static String wrapper(String original) { + return "`" + original + "`"; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.connector.jdbc.source.dialect.DatabaseDialectFactory b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.connector.jdbc.source.dialect.DatabaseDialectFactory new file mode 100644 index 0000000000..8524b42ac8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.connector.jdbc.source.dialect.DatabaseDialectFactory @@ -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. + +mysql=org.apache.eventmesh.connector.jdbc.source.dialect.mysql.MysqlDatabaseDialectFactory diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.connector.jdbc.source.dialect.cdc.CdcEngineFactory b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.connector.jdbc.source.dialect.cdc.CdcEngineFactory new file mode 100644 index 0000000000..06eb1b99e7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.connector.jdbc.source.dialect.cdc.CdcEngineFactory @@ -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. + +mysql=org.apache.eventmesh.connector.jdbc.source.dialect.cdc.mysql.MysqlCdcEngineFactory diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotEngineFactory b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotEngineFactory new file mode 100644 index 0000000000..39075175e2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.SnapshotEngineFactory @@ -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. + +mysql=org.apache.eventmesh.connector.jdbc.source.dialect.snapshot.mysql.MysqlSnapshotEngineFactory diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/log4j2.xml b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..cd699adad8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/log4j2.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/source-config.yml new file mode 100644 index 0000000000..0ec393819a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10001 + subject: TopicTest + idc: FT + env: PRD + group: rocketmqSource + appId: 5032 + userName: jdbcSourceUser + passWord: jdbcPassWord +sourceConnectorConfig: + maxTask: 10 #max task number + batchMaxRows: 100 + skipSnapshot: false + snapshotMaxThreads: 10 + snapshotSchema: true + snapshotData: true + snapshotFetchSize: 100 + databaseType: mysql + databaseIncludeList: + databaseExcludeList: + tableIncludeList: + tableExcludeList: + jdbcConfig: + hostname: localhost + port: 3306 + user: root + password: xxxxx + initialStatements: + connectTimeout: 10 + mysqlConfig: + serverId: 123 + keepAlive: true + keepAliveInterval: 6000 +offsetStorageConfig: + offsetStorageType: nacos + offsetStorageAddr: 127.0.0.1:8848 + extensions: { + #same with topic + dataId: TopicTest, + #same with group + group: rocketmqSource + } \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableIdTest.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableIdTest.java new file mode 100644 index 0000000000..8a76906119 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/table/catalog/TableIdTest.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.jdbc.table.catalog; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Test; + +public class TableIdTest { + + @Test + public void testConstructorWithMapper() { + TableId.TableIdToStringMapper customMapper = mock(TableId.TableIdToStringMapper.class); + when(customMapper.toString(any(TableId.class))).thenReturn("custom"); + + TableId tableId = new TableId("catalog", "schema", "table", customMapper); + assertEquals("custom", tableId.getId()); + } + + @Test + public void testConstructorWithDefaultMapper() { + TableId tableId = new TableId("catalog", "schema", "table"); + assertEquals("catalog.schema.table", tableId.getId()); + } + + @Test + public void testToStringMethod() { + TableId tableId = new TableId("catalog", "schema", "table"); + assertEquals("catalog.schema.table", tableId.toString()); + } + + @Test + public void testTablePathMethod() { + TableId tableId = new TableId("catalog", "schema", "table"); + assertEquals("catalog.schema.table", tableId.tablePath()); + } + + @Test + public void testEqualsMethod() { + TableId tableId1 = new TableId("catalog", "schema", "table"); + TableId tableId2 = new TableId("catalog", "schema", "table"); + assertTrue(tableId1.equals(tableId2)); + } + + @Test + public void testHashCodeMethod() { + TableId tableId1 = new TableId("catalog", "schema", "table"); + TableId tableId2 = new TableId("catalog", "schema", "table"); + assertEquals(tableId1.hashCode(), tableId2.hashCode()); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/utils/Antlr4UtilsTest.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/utils/Antlr4UtilsTest.java new file mode 100644 index 0000000000..56d32ab57e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/utils/Antlr4UtilsTest.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.jdbc.utils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.junit.jupiter.api.Test; + +public class Antlr4UtilsTest { + + @Test + public void testGetTextWithContext() { + // Mock the ParserRuleContext and related objects + ParserRuleContext context = mock(ParserRuleContext.class); + Token startToken = mock(Token.class); + Token stopToken = mock(Token.class); + when(context.getStart()).thenReturn(startToken); + when(context.getStop()).thenReturn(stopToken); + when(startToken.getStartIndex()).thenReturn(0); + when(stopToken.getStopIndex()).thenReturn(11); + + // Mock the InputStream + CharStream inputStream = CharStreams.fromString("Hello, World!"); + when(startToken.getInputStream()).thenReturn(inputStream); + + // Call the method being tested + String result = Antlr4Utils.getText(context); + + // Assertions + assertEquals("Hello, World", result); + } + + @Test + public void testGetTextWithParameters() { + // Create a mock ParserRuleContext + ParserRuleContext context = mock(ParserRuleContext.class); + + // Mock the InputStream + String st = "Hello, Universe!"; + CharStream inputStream = CharStreams.fromString(st); + when(context.getStart()).thenReturn(mock(Token.class)); + when(context.getStop()).thenReturn(mock(Token.class)); + when(context.getStart().getInputStream()).thenReturn(inputStream); + + // Call the method being tested + String result = Antlr4Utils.getText(context, 0, st.length() - 2); + + // Assertions + assertEquals("Hello, Universe", result); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/utils/JdbcStringUtilsTest.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/utils/JdbcStringUtilsTest.java new file mode 100644 index 0000000000..0b2e5121fa --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/utils/JdbcStringUtilsTest.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.connector.jdbc.utils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class JdbcStringUtilsTest { + + @Test + public void testIsWrapped() { + assertTrue(JdbcStringUtils.isWrapped("`Hello`")); + assertTrue(JdbcStringUtils.isWrapped("'World'")); + assertTrue(JdbcStringUtils.isWrapped("\"Java\"")); + assertFalse(JdbcStringUtils.isWrapped("NotWrapped")); + assertFalse(JdbcStringUtils.isWrapped("`NotClosed")); + assertFalse(JdbcStringUtils.isWrapped("NotOpened`")); + } + + @Test + public void testWithoutWrapper() { + assertEquals("Hello", JdbcStringUtils.withoutWrapper("`Hello`")); + assertEquals("World", JdbcStringUtils.withoutWrapper("'World'")); + assertEquals("Java", JdbcStringUtils.withoutWrapper("\"Java\"")); + assertEquals("NotWrapped", JdbcStringUtils.withoutWrapper("NotWrapped")); + assertEquals("`NotClosed", JdbcStringUtils.withoutWrapper("`NotClosed")); + assertEquals("NotOpened`", JdbcStringUtils.withoutWrapper("NotOpened`")); + } + + @Test + public void testIsWrappedWithChar() { + assertTrue(JdbcStringUtils.isWrapped('`')); + assertTrue(JdbcStringUtils.isWrapped('\'')); + assertTrue(JdbcStringUtils.isWrapped('\"')); + assertFalse(JdbcStringUtils.isWrapped('A')); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/utils/MysqlUtilsTest.java b/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/utils/MysqlUtilsTest.java new file mode 100644 index 0000000000..c3970f39fe --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-jdbc/src/test/java/org/apache/eventmesh/connector/jdbc/utils/MysqlUtilsTest.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.jdbc.utils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.connector.jdbc.table.catalog.TableId; + +import org.junit.jupiter.api.Test; + +public class MysqlUtilsTest { + + @Test + public void testWrapperWithTableId() { + TableId mockTableId = mock(TableId.class); + when(mockTableId.toString()).thenReturn("test_table"); + + String wrapped = MysqlUtils.wrapper(mockTableId); + + assertEquals("`test_table`", wrapped); + } + + @Test + public void testWrapperWithString() { + String wrapped = MysqlUtils.wrapper("test_string"); + + assertEquals("`test_string`", wrapped); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-kafka/build.gradle b/eventmesh-connectors/eventmesh-connector-kafka/build.gradle new file mode 100644 index 0000000000..98176995bd --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/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-openconnect:eventmesh-openconnect-java") + implementation 'io.cloudevents:cloudevents-kafka:2.4.2' + implementation 'org.apache.kafka:kafka-clients:3.0.0' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-kafka/gradle.properties b/eventmesh-connectors/eventmesh-connector-kafka/gradle.properties new file mode 100644 index 0000000000..4486939e8d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/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=kafka \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/config/KafkaServerConfig.java b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/config/KafkaServerConfig.java new file mode 100644 index 0000000000..2c9ef71fb4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/config/KafkaServerConfig.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.connector.kafka.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; + +@Data +public class KafkaServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; + +} diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/server/KafkaConnectServer.java b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/server/KafkaConnectServer.java new file mode 100644 index 0000000000..973424a18b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/server/KafkaConnectServer.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.connector.kafka.server; + +import org.apache.eventmesh.connector.kafka.config.KafkaServerConfig; +import org.apache.eventmesh.connector.kafka.sink.connector.KafkaSinkConnector; +import org.apache.eventmesh.connector.kafka.source.connector.KafkaSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class KafkaConnectServer { + + public static void main(String[] args) throws Exception { + + KafkaServerConfig serverConfig = ConfigUtil.parse(KafkaServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application kafkaSourceApp = new Application(); + kafkaSourceApp.run(KafkaSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application kafkaSinkApp = new Application(); + kafkaSinkApp.run(KafkaSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/sink/config/KafkaSinkConfig.java b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/sink/config/KafkaSinkConfig.java new file mode 100644 index 0000000000..9bb79551db --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/sink/config/KafkaSinkConfig.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.kafka.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; + +@Data +public class KafkaSinkConfig extends SinkConfig { + + public SinkConnectorConfig connectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..a240bf4f49 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/sink/config/SinkConnectorConfig.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.kafka.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName = "kafkaSink"; + private String topic = "TopicTest"; + private String ack = "all"; + private String bootstrapServers = "127.0.0.1:9092"; + private String keyConverter = "org.apache.kafka.common.serialization.StringSerializer"; + private String valueConverter = "org.apache.kafka.common.serialization.StringSerializer"; + private String maxRequestSize = "1048576"; + private String bufferMemory = "33554432"; + private String batchSize = "16384"; + private String lingerMs = "0"; + private String requestTimeoutMs = "30000"; + private String maxInFightRequestsPerConnection = "5"; + private String retries = "0"; + private String compressionType = "none"; +} diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/sink/connector/KafkaSinkConnector.java b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/sink/connector/KafkaSinkConnector.java new file mode 100644 index 0000000000..49b7e88f19 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/sink/connector/KafkaSinkConnector.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.connector.kafka.sink.connector; + +import org.apache.eventmesh.connector.kafka.sink.config.KafkaSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.header.Header; +import org.apache.kafka.common.header.internals.RecordHeader; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class KafkaSinkConnector implements Sink { + + private KafkaSinkConfig sinkConfig; + + private final Properties props = new Properties(); + Producer producer; + + @Override + public Class configClass() { + return KafkaSinkConfig.class; + } + + @Override + public void init(Config config) { + this.sinkConfig = (KafkaSinkConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (KafkaSinkConfig) sinkConnectorContext.getSinkConfig(); + doInit(); + } + + private void doInit() { + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, sinkConfig.getConnectorConfig().getBootstrapServers()); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, sinkConfig.getConnectorConfig().getKeyConverter()); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, sinkConfig.getConnectorConfig().getValueConverter()); + props.put(ProducerConfig.ACKS_CONFIG, sinkConfig.getConnectorConfig().getAck()); + props.put(ProducerConfig.MAX_REQUEST_SIZE_CONFIG, sinkConfig.getConnectorConfig().getMaxRequestSize()); + props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, sinkConfig.getConnectorConfig().getBufferMemory()); + props.put(ProducerConfig.BATCH_SIZE_CONFIG, sinkConfig.getConnectorConfig().getBatchSize()); + props.put(ProducerConfig.LINGER_MS_CONFIG, sinkConfig.getConnectorConfig().getLingerMs()); + props.put(ProducerConfig.REQUEST_TIMEOUT_MS_CONFIG, sinkConfig.getConnectorConfig().getRequestTimeoutMs()); + props.put(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, sinkConfig.getConnectorConfig().getMaxInFightRequestsPerConnection()); + props.put(ProducerConfig.RETRIES_CONFIG, sinkConfig.getConnectorConfig().getRetries()); + props.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, sinkConfig.getConnectorConfig().getCompressionType()); + producer = new KafkaProducer<>(props); + } + + @Override + public void start() throws Exception { + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + producer.close(); + } + + @Override + public void put(List sinkRecords) { + try { + for (ConnectRecord connectRecord : sinkRecords) { + ProducerRecord message = convertRecordToMessage(connectRecord); + producer.send(message, (metadata, exception) -> { + if (exception == null) { + log.debug("Produced message to topic:{},partition:{},offset:{}", metadata.topic(), metadata.partition(), metadata.offset()); + } else { + log.error("Failed to produce message:{}", exception.getMessage()); + } + }); + } + } catch (Exception e) { + log.error("Failed to produce message:{}", e.getMessage()); + } + } + + public ProducerRecord convertRecordToMessage(ConnectRecord connectRecord) { + List
headers = new ArrayList<>(); + for (String key : connectRecord.getExtensions().keySet()) { + headers.add(new RecordHeader(key, connectRecord.getExtension(key).getBytes(StandardCharsets.UTF_8))); + } + ProducerRecord message = new ProducerRecord(this.sinkConfig.getConnectorConfig().getTopic(), null, "", + new String((byte[]) connectRecord.getData(), StandardCharsets.UTF_8), headers); + return message; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/source/config/KafkaSourceConfig.java b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/source/config/KafkaSourceConfig.java new file mode 100644 index 0000000000..4319ec96d7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/source/config/KafkaSourceConfig.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.connector.kafka.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; + +@Data +public class KafkaSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..2d2f52f85c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/source/config/SourceConnectorConfig.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.connector.kafka.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName = "kafkaSource"; + private String topic = "TopicTest"; + private String bootstrapServers = "127.0.0.1:9092"; + private String groupID = "kafkaSource"; + private String keyConverter = "org.apache.kafka.common.serialization.StringDeserializer"; + private String valueConverter = "org.apache.kafka.common.serialization.StringDeserializer"; + private String autoCommitIntervalMS = "1000"; + private String enableAutoCommit = "false"; + private String sessionTimeoutMS = "10000"; + private String maxPollRecords = "1000"; + private int pollTimeOut = 100; +} diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/source/connector/KafkaSourceConnector.java b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/source/connector/KafkaSourceConnector.java new file mode 100644 index 0000000000..99fa73b580 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/java/org/apache/eventmesh/connector/kafka/source/connector/KafkaSourceConnector.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.kafka.source.connector; + +import org.apache.eventmesh.connector.kafka.source.config.KafkaSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +public class KafkaSourceConnector implements Source { + + private KafkaSourceConfig sourceConfig; + + private KafkaConsumer kafkaConsumer; + + private int pollTimeOut = 100; + + @Override + public Class configClass() { + return KafkaSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + this.sourceConfig = (KafkaSourceConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (KafkaSourceConfig) sourceConnectorContext.getSourceConfig(); + doInit(); + } + + private void doInit() { + Properties props = new Properties(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, sourceConfig.getConnectorConfig().getBootstrapServers()); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, sourceConfig.getConnectorConfig().getKeyConverter()); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, sourceConfig.getConnectorConfig().getValueConverter()); + props.put(ConsumerConfig.GROUP_ID_CONFIG, sourceConfig.getConnectorConfig().getGroupID()); + props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, sourceConfig.getConnectorConfig().getEnableAutoCommit()); + props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, sourceConfig.getConnectorConfig().getMaxPollRecords()); + props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, sourceConfig.getConnectorConfig().getAutoCommitIntervalMS()); + props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, sourceConfig.getConnectorConfig().getSessionTimeoutMS()); + this.pollTimeOut = sourceConfig.getConnectorConfig().getPollTimeOut(); + this.kafkaConsumer = new KafkaConsumer<>(props); + } + + @Override + public void start() throws Exception { + kafkaConsumer.subscribe(Collections.singleton(sourceConfig.getConnectorConfig().getTopic())); + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + kafkaConsumer.unsubscribe(); + } + + @Override + public List poll() { + ConsumerRecords records = kafkaConsumer.poll(Duration.ofMillis(pollTimeOut)); + List connectRecords = new ArrayList<>(records.count()); + for (ConsumerRecord record : records) { + Long timestamp = System.currentTimeMillis(); + String key = record.key(); + String value = record.value(); + RecordPartition recordPartition = convertToRecordPartition(record.topic(), record.partition()); + RecordOffset recordOffset = convertToRecordOffset(record.offset()); + ConnectRecord connectRecord = new ConnectRecord(recordPartition, recordOffset, timestamp, value); + connectRecord.addExtension("key", key); + connectRecords.add(connectRecord); + } + kafkaConsumer.commitAsync(); + return connectRecords; + } + + public static RecordOffset convertToRecordOffset(Long offset) { + Map offsetMap = new HashMap<>(); + offsetMap.put("queueOffset", offset + ""); + return new RecordOffset(offsetMap); + } + + public static RecordPartition convertToRecordPartition(String topic, int partition) { + Map map = new HashMap<>(); + map.put("topic", topic); + map.put("partition", String.valueOf(partition)); + return new RecordPartition(map); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-kafka/src/main/resources/server-config.yml new file mode 100644 index 0000000000..0cd7b5b5ab --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: false diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-kafka/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..b5c35b5434 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: kafkaSink + appId: 5031 + userName: kafkaSinkUser + passWord: kafkaPassWord +connectorConfig: + connectorName: kafkaSink + bootstrapServers: 127.0.0.1:9092 + topic: TopicTest + keyConverter: org.apache.kafka.common.serialization.StringSerializer + valueConverter: org.apache.kafka.common.serialization.StringSerializer + diff --git a/eventmesh-connectors/eventmesh-connector-kafka/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-kafka/src/main/resources/source-config.yml new file mode 100644 index 0000000000..4300c749f0 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-kafka/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: kafkaSource + appId: 5032 + userName: kafkaSourceUser + passWord: kafkaPassWord +connectorConfig: + connectorName: kafkaSource + bootstrapServers: 127.0.0.1:9092 + topic: TopicTest + groupID: kafkaSource + sessionTimeoutMS: 10000 + maxPollRecords: 1000 diff --git a/eventmesh-connectors/eventmesh-connector-knative/build.gradle b/eventmesh-connectors/eventmesh-connector-knative/build.gradle new file mode 100644 index 0000000000..2380a6b192 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/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. + */ + +configurations { + implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' + implementation.exclude group: 'log4j', module: 'log4j' +} + +dependencies { + api project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation project(":eventmesh-common") + + implementation 'org.asynchttpclient:async-http-client' + + implementation 'io.cloudevents:cloudevents-json-jackson' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} diff --git a/eventmesh-connectors/eventmesh-connector-knative/gradle.properties b/eventmesh-connectors/eventmesh-connector-knative/gradle.properties new file mode 100644 index 0000000000..27e6abf1c3 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/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. +# +knative_version=1.5 +pluginType=connector +pluginName=knative \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeHeaders.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/cloudevent/KnativeHeaders.java similarity index 94% rename from eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeHeaders.java rename to eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/cloudevent/KnativeHeaders.java index 1f998a4b2e..217023ddef 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeHeaders.java +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/cloudevent/KnativeHeaders.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.storage.knative.cloudevent.impl; +package org.apache.eventmesh.connector.knative.cloudevent; public class KnativeHeaders { diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/KnativeMessageFactory.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/cloudevent/KnativeMessageFactory.java similarity index 81% rename from eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/KnativeMessageFactory.java rename to eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/cloudevent/KnativeMessageFactory.java index 91ed60778d..d2d82e2033 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/KnativeMessageFactory.java +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/cloudevent/KnativeMessageFactory.java @@ -15,12 +15,9 @@ * limitations under the License. */ -package org.apache.eventmesh.storage.knative.cloudevent; - -import org.apache.eventmesh.storage.knative.cloudevent.impl.KnativeMessageWriter; +package org.apache.eventmesh.connector.knative.cloudevent; import java.nio.charset.StandardCharsets; -import java.util.Properties; import io.cloudevents.CloudEvent; @@ -40,8 +37,4 @@ public static String createReader(final CloudEvent message) { } return new String(message.getData().toBytes(), StandardCharsets.UTF_8); } - - public static KnativeMessageWriter createWriter(final Properties properties) { - return new KnativeMessageWriter(properties); - } } diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/config/KnativeServerConfig.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/config/KnativeServerConfig.java new file mode 100644 index 0000000000..4125132ad7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/config/KnativeServerConfig.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.knative.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class KnativeServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/server/KnativeConnectServer.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/server/KnativeConnectServer.java new file mode 100644 index 0000000000..1080261677 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/server/KnativeConnectServer.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.knative.server; + +import org.apache.eventmesh.connector.knative.config.KnativeServerConfig; +import org.apache.eventmesh.connector.knative.sink.connector.KnativeSinkConnector; +import org.apache.eventmesh.connector.knative.source.connector.KnativeSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class KnativeConnectServer { + + public static void main(String[] args) throws Exception { + + KnativeServerConfig serverConfig = ConfigUtil.parse(KnativeServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application knativeSourceApp = new Application(); + knativeSourceApp.run(KnativeSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application knativeSinkApp = new Application(); + knativeSinkApp.run(KnativeSinkConnector.class); + } + + } +} diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/sink/config/KnativeSinkConfig.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/sink/config/KnativeSinkConfig.java new file mode 100644 index 0000000000..85bb38a90b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/sink/config/KnativeSinkConfig.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.connector.knative.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class KnativeSinkConfig extends SinkConfig { + + public SinkConnectorConfig connectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..5694c643f8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/sink/config/SinkConnectorConfig.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.connector.knative.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + public String emurl; + + public String serviceAddr; + +} diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/sink/connector/KnativeSinkConnector.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/sink/connector/KnativeSinkConnector.java new file mode 100644 index 0000000000..fdf5b1056b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/sink/connector/KnativeSinkConnector.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.connector.knative.sink.connector; + +import static org.asynchttpclient.Dsl.asyncHttpClient; + +import org.apache.eventmesh.connector.knative.cloudevent.KnativeHeaders; +import org.apache.eventmesh.connector.knative.cloudevent.KnativeMessageFactory; +import org.apache.eventmesh.connector.knative.sink.config.KnativeSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.asynchttpclient.AsyncHttpClient; +import org.asynchttpclient.ListenableFuture; +import org.asynchttpclient.Response; +import org.asynchttpclient.util.HttpConstants; + +import io.cloudevents.CloudEvent; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class KnativeSinkConnector implements Sink { + + private KnativeSinkConfig sinkConfig; + + private transient AsyncHttpClient asyncHttpClient; + + private static final AtomicBoolean started = new AtomicBoolean(false); + + @Override + public Class configClass() { + return KnativeSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (KnativeSinkConfig) sinkConnectorContext.getSinkConfig(); + this.asyncHttpClient = asyncHttpClient(); + } + + @Override + public void start() throws Exception { + started.compareAndSet(false, true); + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + started.compareAndSet(true, false); + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + CloudEvent cloudEvent = CloudEventUtil.convertRecordToEvent(connectRecord); + try { + ListenableFuture execute = asyncHttpClient.preparePost("http://" + sinkConfig.getConnectorConfig().getServiceAddr()) + .addHeader(KnativeHeaders.CONTENT_TYPE, cloudEvent.getDataContentType()) + .addHeader(KnativeHeaders.CE_ID, cloudEvent.getId()) + .addHeader(KnativeHeaders.CE_SPECVERSION, String.valueOf(cloudEvent.getSpecVersion())) + .addHeader(KnativeHeaders.CE_TYPE, cloudEvent.getType()) + .addHeader(KnativeHeaders.CE_SOURCE, String.valueOf(cloudEvent.getSource())) + .setBody(KnativeMessageFactory.createReader(cloudEvent)) + .execute(); + + Response response = execute.get(10, TimeUnit.SECONDS); + if (response.getStatusCode() != HttpConstants.ResponseStatusCodes.OK_200) { + log.error("[KnativeSinkConnector] sendResult fail : {}", response.getResponseBody());; + } + } catch (InterruptedException e) { + Thread currentThread = Thread.currentThread(); + log.warn("[KnativeSinkConnector] Interrupting thread {} due to exception {}", currentThread.getName(), e.getMessage()); + currentThread.interrupt(); + } catch (Exception e) { + log.error("[KnativeSinkConnector] sendResult has error : ", e); + } + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/source/config/KnativeSourceConfig.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/source/config/KnativeSourceConfig.java new file mode 100644 index 0000000000..8ef36a8d78 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/source/config/KnativeSourceConfig.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.connector.knative.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class KnativeSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..8d21c86b7b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/source/config/SourceConnectorConfig.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.connector.knative.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + public String emurl; + + public String serviceAddr; + +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/source/connector/KnativeSourceConnector.java b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/source/connector/KnativeSourceConnector.java new file mode 100644 index 0000000000..239c39a802 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/java/org/apache/eventmesh/connector/knative/source/connector/KnativeSourceConnector.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.connector.knative.source.connector; + +import org.apache.eventmesh.connector.knative.source.config.KnativeSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class KnativeSourceConnector implements Source { + + private KnativeSourceConfig sourceConfig; + + private static final AtomicBoolean started = new AtomicBoolean(false); + + @Override + public Class configClass() { + return KnativeSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (KnativeSourceConfig) sourceConnectorContext.getSourceConfig(); + } + + @Override + public void start() throws Exception { + started.compareAndSet(false, true); + } + + @Override + public void commit(ConnectRecord record) { + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + started.compareAndSet(true, false); + } + + @Override + public List poll() { + // todo: create a sink service and expose a public endpoint to Knative broker + // https://knative.dev/docs/eventing/sinks/ + return null; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-knative/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-knative/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..6340b667ec --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: knativeSink + appId: 5031 + userName: knativeSinkUser + passWord: knativePassWord +connectorConfig: + connectorName: knativeSink + emurl: 127.0.0.1 + serviceAddr: cloudevents-player.default.127.0.0.1.sslip.io + diff --git a/eventmesh-connectors/eventmesh-connector-knative/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-knative/src/main/resources/source-config.yml new file mode 100644 index 0000000000..dffc9cd020 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-knative/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: knativeSource + appId: 5032 + userName: knativeSourceUser + passWord: knativePassWord +connectorConfig: + connectorName: knativeSource + emurl: 127.0.0.1 + serviceAddr: cloudevents-player.default.127.0.0.1.sslip.io +offsetStorageConfig: + offsetStorageType: nacos + offsetStorageAddr: 127.0.0.1:8848 + extensions: { + #same with connectorName + dataId: knativeSource, + #same with group + group: knativeSource + } diff --git a/eventmesh-connectors/eventmesh-connector-lark/build.gradle b/eventmesh-connectors/eventmesh-connector-lark/build.gradle new file mode 100644 index 0000000000..7cdd35b053 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/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. + */ + +List lark = [ + "com.larksuite.oapi:oapi-sdk:$lark_version", + "com.github.rholder:guava-retrying:$guava_retrying_version", + "org.apache.httpcomponents:httpclient", + project(":eventmesh-common") +] + +dependencies { + api project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation lark + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation "org.mockito:mockito-inline" + testImplementation "org.mockito:mockito-junit-jupiter" +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-lark/gradle.properties b/eventmesh-connectors/eventmesh-connector-lark/gradle.properties new file mode 100644 index 0000000000..90f0d877f8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/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. +# +lark_version=2.0.28 +guava_retrying_version=2.0.0 +pluginType=connector +pluginName=lark \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/ConnectRecordExtensionKeys.java b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/ConnectRecordExtensionKeys.java new file mode 100644 index 0000000000..42274199e3 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/ConnectRecordExtensionKeys.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.connector.lark; + +/** + * Constants of record extension key. + */ +public interface ConnectRecordExtensionKeys { + + /** + * {@code text} or {@code markdown}, otherwise use {@code text} to replace. + */ + String TEMPLATE_TYPE_4_LARK = "templatetype4lark"; + + /** + * The value format is {@code id,name;id,name;}.Recommend to use {@code open_id} as {@code id}. + *

+ * To prevent bad situations, you should ensure that the {@code id} is valid + */ + String AT_USERS_4_LARK = "atusers4lark"; + + /** + * true or false + */ + String AT_ALL_4_LARK = "atall4lark"; + + String MARKDOWN_MESSAGE_TITLE_4_LARK = "markdownmessagetitle4lark"; +} diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/config/LarkConnectServerConfig.java b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/config/LarkConnectServerConfig.java new file mode 100644 index 0000000000..6d0428056e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/config/LarkConnectServerConfig.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.connector.lark.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class LarkConnectServerConfig extends Config { + + private boolean sinkEnable; + +} diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/config/LarkMessageTemplateType.java b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/config/LarkMessageTemplateType.java new file mode 100644 index 0000000000..e99afcaa6b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/config/LarkMessageTemplateType.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.connector.lark.config; + +import java.util.Arrays; + +import lombok.Getter; + +@Getter +public enum LarkMessageTemplateType { + + PLAIN_TEXT("text"), + MARKDOWN("markdown"); + + private final String templateKey; + + LarkMessageTemplateType(String templateKey) { + this.templateKey = templateKey; + } + + public static LarkMessageTemplateType of(String templateKey) { + return Arrays.stream(values()) + .filter(v -> v.getTemplateKey().equals(templateKey)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("TemplateKey: " + templateKey + " not found.")); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/server/LarkConnectServer.java b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/server/LarkConnectServer.java new file mode 100644 index 0000000000..c6ec73c5a4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/server/LarkConnectServer.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.connector.lark.server; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.lark.config.LarkConnectServerConfig; +import org.apache.eventmesh.connector.lark.sink.connector.LarkSinkConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +public class LarkConnectServer { + + public static void main(String[] args) throws Exception { + + LarkConnectServerConfig larkConnectServerConfig = ConfigUtil.parse(LarkConnectServerConfig.class, + Constants.CONNECT_SERVER_CONFIG_FILE_NAME); + + if (larkConnectServerConfig.isSinkEnable()) { + Application application = new Application(); + application.run(LarkSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/ImServiceHandler.java b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/ImServiceHandler.java new file mode 100644 index 0000000000..e61940ce3d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/ImServiceHandler.java @@ -0,0 +1,346 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.lark.sink; + +import static org.apache.eventmesh.connector.lark.sink.connector.LarkSinkConnector.getTenantAccessToken; + +import org.apache.eventmesh.connector.lark.ConnectRecordExtensionKeys; +import org.apache.eventmesh.connector.lark.config.LarkMessageTemplateType; +import org.apache.eventmesh.connector.lark.sink.config.SinkConnectorConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.commons.text.StringEscapeUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.LongAdder; + +import com.github.rholder.retry.Attempt; +import com.github.rholder.retry.RetryException; +import com.github.rholder.retry.RetryListener; +import com.github.rholder.retry.Retryer; +import com.github.rholder.retry.RetryerBuilder; +import com.github.rholder.retry.StopStrategies; +import com.github.rholder.retry.WaitStrategies; +import com.lark.oapi.Client; +import com.lark.oapi.card.enums.MessageCardHeaderTemplateEnum; +import com.lark.oapi.card.model.MessageCard; +import com.lark.oapi.card.model.MessageCardConfig; +import com.lark.oapi.card.model.MessageCardElement; +import com.lark.oapi.card.model.MessageCardHeader; +import com.lark.oapi.card.model.MessageCardMarkdown; +import com.lark.oapi.card.model.MessageCardPlainText; +import com.lark.oapi.core.httpclient.OkHttpTransport; +import com.lark.oapi.core.request.RequestOptions; +import com.lark.oapi.core.utils.Lists; +import com.lark.oapi.okhttp.OkHttpClient; +import com.lark.oapi.service.im.v1.ImService; +import com.lark.oapi.service.im.v1.enums.MsgTypeEnum; +import com.lark.oapi.service.im.v1.model.CreateMessageReq; +import com.lark.oapi.service.im.v1.model.CreateMessageReqBody; +import com.lark.oapi.service.im.v1.model.CreateMessageResp; +import com.lark.oapi.service.im.v1.model.ext.MessageText; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ImServiceHandler { + + private SinkConnectorConfig sinkConnectorConfig; + + private ImService imService; + + private Retryer retryer; + + private ExecutorService sinkAsyncWorker; + private ExecutorService cleanerWorker; + private ScheduledExecutorService retryWorker; + + private static final LongAdder redoSinkNum = new LongAdder(); + + public ImServiceHandler() { + } + + public static ImServiceHandler create(SinkConnectorConfig sinkConnectorConfig) { + ImServiceHandler imServiceHandler = new ImServiceHandler(); + imServiceHandler.sinkConnectorConfig = sinkConnectorConfig; + imServiceHandler.imService = Client.newBuilder(sinkConnectorConfig.getAppId(), sinkConnectorConfig.getAppSecret()) + .httpTransport(new OkHttpTransport(new OkHttpClient().newBuilder() + .callTimeout(3L, TimeUnit.SECONDS) + .build())) + .disableTokenCache() + .requestTimeout(3, TimeUnit.SECONDS) + .build() + .im(); + + long fixedWait = Long.parseLong(sinkConnectorConfig.getRetryDelayInMills()); + int maxRetryTimes = Integer.parseInt(sinkConnectorConfig.getMaxRetryTimes()) + 1; + if (Boolean.parseBoolean(sinkConnectorConfig.getSinkAsync())) { + int availableProcessors = Runtime.getRuntime().availableProcessors(); + imServiceHandler.sinkAsyncWorker = Executors.newFixedThreadPool(availableProcessors, r -> { + Thread thread = new Thread(r); + thread.setDaemon(true); + thread.setName("eventmesh-connector-lark-sinkAsyncWorker"); + return thread; + }); + + imServiceHandler.cleanerWorker = Executors.newFixedThreadPool(availableProcessors, r -> { + Thread thread = new Thread(r); + thread.setDaemon(true); + thread.setName("eventmesh-connector-lark-cleanerWorker"); + return thread; + }); + + imServiceHandler.retryWorker = Executors.newScheduledThreadPool(availableProcessors, r -> { + Thread thread = new Thread(r); + thread.setDaemon(true); + thread.setName("eventmesh-connector-lark-retryWorker"); + return thread; + }); + } else { + imServiceHandler.retryer = RetryerBuilder.newBuilder() + .retryIfException() + .retryIfResult(Objects::nonNull) + .withWaitStrategy(WaitStrategies.fixedWait(fixedWait, TimeUnit.MILLISECONDS)) + .withStopStrategy(StopStrategies.stopAfterAttempt(maxRetryTimes)) + .withRetryListener(new RetryListener() { + + @SneakyThrows + @Override + public void onRetry(Attempt attempt) { + + long times = attempt.getAttemptNumber(); + if (times > 1) { + redoSinkNum.increment(); + log.info("Total redo sink task num : [{}]", redoSinkNum.sum()); + log.warn("Retry sink event to lark | times=[{}]", attempt.getAttemptNumber() - 1); + } + } + }) + .build(); + } + + return imServiceHandler; + } + + public void sink(ConnectRecord connectRecord) throws ExecutionException, RetryException { + Map> headers = new HashMap<>(); + headers.put("Content-Type", Lists.newArrayList("application/json; charset=utf-8")); + + RequestOptions requestOptions = RequestOptions.newBuilder() + .tenantAccessToken(getTenantAccessToken(sinkConnectorConfig.getAppId(), sinkConnectorConfig.getAppSecret())) + .headers(headers) + .build(); + + retryer.call(() -> { + CreateMessageReq createMessageReq = convertCreateMessageReq(connectRecord); + CreateMessageResp resp = imService.message().create(createMessageReq, requestOptions); + if (resp.getCode() != 0) { + log.warn("Sinking event to lark failure | code:[{}] | msg:[{}] | err:[{}]", resp.getCode(), resp.getMsg(), resp.getError()); + return connectRecord; + } + return null; + }); + } + + public void sinkAsync(ConnectRecord connectRecord) { + Map> headers = new HashMap<>(); + headers.put("Content-Type", Lists.newArrayList("application/json; charset=utf-8")); + + RequestOptions requestOptions = RequestOptions.newBuilder() + .tenantAccessToken(getTenantAccessToken(sinkConnectorConfig.getAppId(), sinkConnectorConfig.getAppSecret())) + .headers(headers) + .build(); + + CreateMessageReq createMessageReq = convertCreateMessageReq(connectRecord); + + long fixedWait = Long.parseLong(sinkConnectorConfig.getRetryDelayInMills()); + int maxRetryTimes = Integer.parseInt(sinkConnectorConfig.getMaxRetryTimes()) + 1; + LongAdder cnt = new LongAdder(); + AtomicBoolean isAck = new AtomicBoolean(false); + Runnable task = () -> CompletableFuture + .supplyAsync(() -> { + try { + cnt.increment(); + return imService.message().create(createMessageReq, requestOptions); + } catch (Exception e) { + throw new RuntimeException(e); + } + }, sinkAsyncWorker) + .whenCompleteAsync((resp, e) -> { + if (cnt.sum() > 1) { + redoSinkNum.increment(); + log.info("Total redo sink task num : [{}]", redoSinkNum.sum()); + log.warn("Retry sink event to lark | times=[{}]", cnt.sum() - 1); + } + if (Objects.nonNull(e)) { + log.error("eventmesh-connector-lark internal exception.", e); + return; + } + if (resp.getCode() != 0) { + log.warn("Sinking event to lark failure | code:[{}] | msg:[{}] | err:[{}]", resp.getCode(), resp.getMsg(), resp.getError()); + return; + } + isAck.set(true); + }); + + ScheduledFuture future = retryWorker.scheduleAtFixedRate(task, 0L, fixedWait, TimeUnit.MILLISECONDS); + cleanerWorker.submit(() -> { + while (true) { + // complete task + if (isAck.get() || cnt.sum() >= maxRetryTimes) { + future.cancel(true); + return; + } + } + }); + } + + private CreateMessageReq convertCreateMessageReq(ConnectRecord connectRecord) { + CreateMessageReqBody.Builder bodyBuilder = CreateMessageReqBody.newBuilder() + .receiveId(sinkConnectorConfig.getReceiveId()) + .uuid(UUID.randomUUID().toString()); + + String templateTypeKey = connectRecord.getExtension(ConnectRecordExtensionKeys.TEMPLATE_TYPE_4_LARK); + if (null == templateTypeKey || "null".equals(templateTypeKey)) { + templateTypeKey = LarkMessageTemplateType.PLAIN_TEXT.getTemplateKey(); + } + LarkMessageTemplateType templateType = LarkMessageTemplateType.of(templateTypeKey); + if (LarkMessageTemplateType.PLAIN_TEXT == templateType) { + bodyBuilder.content(createTextContent(connectRecord)) + .msgType(MsgTypeEnum.MSG_TYPE_TEXT.getValue()); + } else if (LarkMessageTemplateType.MARKDOWN == templateType) { + String title = Optional.ofNullable(connectRecord.getExtension(ConnectRecordExtensionKeys.MARKDOWN_MESSAGE_TITLE_4_LARK)) + .orElse("EventMesh-Message"); + bodyBuilder.content(createInteractiveContent(connectRecord, title)) + .msgType(MsgTypeEnum.MSG_TYPE_INTERACTIVE.getValue()); + } + + return CreateMessageReq.newBuilder() + .receiveIdType(sinkConnectorConfig.getReceiveIdType()) + .createMessageReqBody(bodyBuilder.build()) + .build(); + } + + private String createTextContent(ConnectRecord connectRecord) { + MessageText.Builder msgBuilder = MessageText.newBuilder(); + + if (needAtAll(connectRecord)) { + msgBuilder.atAll(); + } + String atUsers = needAtUser(connectRecord); + if (!atUsers.isEmpty()) { + String[] users = atUsers.split(";"); + + for (String user : users) { + String[] kv = user.split(","); + msgBuilder.atUser(kv[0], kv[1]); + } + } + + String escapedString = StringEscapeUtils.escapeJava(new String((byte[]) connectRecord.getData())); + return msgBuilder.text(escapedString).build(); + } + + private String createInteractiveContent(ConnectRecord connectRecord, String title) { + StringBuilder sb = new StringBuilder(); + if (needAtAll(connectRecord)) { + atAll(sb); + } + String atUsers = needAtUser(connectRecord); + if (!atUsers.isEmpty()) { + String[] users = atUsers.split(";"); + + for (String user : users) { + String[] kv = user.split(","); + atUser(sb, kv[0]); + } + } + sb.append(new String((byte[]) connectRecord.getData())); + + MessageCardConfig config = MessageCardConfig.newBuilder() + .enableForward(true) + .wideScreenMode(true) + .updateMulti(true) + .build(); + + // header + MessageCardHeader header = MessageCardHeader.newBuilder() + .template(MessageCardHeaderTemplateEnum.BLUE) + .title(MessageCardPlainText.newBuilder() + .content(title) + .build()) + .build(); + + MessageCard content = MessageCard.newBuilder() + .config(config) + .header(header) + .elements(new MessageCardElement[]{ + MessageCardMarkdown.newBuilder().content(sb.toString()).build() + }) + .build(); + + return content.String(); + } + + private boolean needAtAll(ConnectRecord connectRecord) { + String atAll = connectRecord.getExtension(ConnectRecordExtensionKeys.AT_ALL_4_LARK); + return null != atAll && !"null".equals(atAll) && Boolean.parseBoolean(atAll); + } + + private String needAtUser(ConnectRecord connectRecord) { + String atUsers = connectRecord.getExtension(ConnectRecordExtensionKeys.AT_USERS_4_LARK); + return null != atUsers && !"null".equals(atUsers) ? atUsers : ""; + } + + /** + * For markdown template type. + * + * @param sb StringBuilder + */ + private void atAll(StringBuilder sb) { + sb.append("") + .append(""); + } + + /** + * For markdown template type + * + * @param sb StringBuilder + * @param userId open_id/union_id/user_id, recommend to use open_id. Custom robots can only be used open_id, + */ + private void atUser(StringBuilder sb, String userId) { + sb.append("") + .append(""); + } +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/config/LarkSinkConfig.java b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/config/LarkSinkConfig.java new file mode 100644 index 0000000000..a97ece91b0 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/config/LarkSinkConfig.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.connector.lark.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class LarkSinkConfig extends SinkConfig { + + public SinkConnectorConfig sinkConnectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..cde3aa6737 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/config/SinkConnectorConfig.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.connector.lark.sink.config; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.commons.lang3.StringUtils; + +import com.lark.oapi.service.im.v1.enums.ReceiveIdTypeEnum; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName = "larkSink"; + + /** + * Can not be blank + */ + private String appId; + + /** + * Can not be blank + */ + private String appSecret; + + /** + * The value is {@code open_id/user_id/union_id/email/chat_id}. + * Recommend to use open_id. + */ + private String receiveIdType = "open_id"; + + /** + * Can not be blank.And it needs to correspond to {@code receiveIdType} + */ + private String receiveId; + + /** + * When sinking CouldEvent to lark, choose to call + * {@link org.apache.eventmesh.connector.lark.sink.ImServiceHandler#sink(ConnectRecord)} + * or {@link org.apache.eventmesh.connector.lark.sink.ImServiceHandler#sinkAsync(ConnectRecord)} + */ + private String sinkAsync = "true"; + + private String maxRetryTimes = "3"; + + private String retryDelayInMills = "1000"; + + public void validateSinkConfiguration() { + // validate blank + if (StringUtils.isAnyBlank(appId, appSecret, receiveId)) { + throw new IllegalArgumentException("appId or appSecret or receiveId is blank,please check it."); + } + + // validate receiveIdType + if (!StringUtils.containsAny(receiveIdType, ReceiveIdTypeEnum.CHAT_ID.getValue(), + ReceiveIdTypeEnum.EMAIL.getValue(), + ReceiveIdTypeEnum.OPEN_ID.getValue(), + ReceiveIdTypeEnum.USER_ID.getValue(), + ReceiveIdTypeEnum.UNION_ID.getValue())) { + throw new IllegalArgumentException( + String.format("sinkConnectorConfig.receiveIdType=[%s], Invalid.", receiveIdType)); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/connector/LarkSinkConnector.java b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/connector/LarkSinkConnector.java new file mode 100644 index 0000000000..d1ee1caa40 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/java/org/apache/eventmesh/connector/lark/sink/connector/LarkSinkConnector.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.connector.lark.sink.connector; + +import static org.apache.eventmesh.connector.lark.sink.ImServiceHandler.create; + +import org.apache.eventmesh.connector.lark.sink.ImServiceHandler; +import org.apache.eventmesh.connector.lark.sink.config.LarkSinkConfig; +import org.apache.eventmesh.connector.lark.sink.config.SinkConnectorConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import com.github.rholder.retry.RetryException; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.lark.oapi.Client; +import com.lark.oapi.core.enums.AppType; +import com.lark.oapi.core.request.SelfBuiltTenantAccessTokenReq; +import com.lark.oapi.core.response.TenantAccessTokenResp; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class LarkSinkConnector implements Sink { + + public static final String TENANT_ACCESS_TOKEN = "tenant_access_token"; + + /** + * Global Access Credential Manager to replace lark build-in tokenCache. + *

+ * If you plan to extend the method of obtaining other credentials, + * you can refer to the implementation of {@link #getTenantAccessToken(String, String)} + *

+ * If the expiration mechanism provided by lark conflicts with the expiration time set in AUTH_CACHE, + * you can try to modify it. + */ + public static final Cache AUTH_CACHE = CacheBuilder.newBuilder() + .initialCapacity(12) + .maximumSize(10) + .concurrencyLevel(5) + .expireAfterWrite(30, TimeUnit.MINUTES) + .build(); + + private LarkSinkConfig sinkConfig; + + private ImServiceHandler imServiceHandler; + + private final AtomicBoolean started = new AtomicBoolean(false); + + @Override + public Class configClass() { + return LarkSinkConfig.class; + } + + @Override + public void init(Config config) { + } + + @Override + public void init(ConnectorContext connectorContext) { + // init config for lark sink connector + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (LarkSinkConfig) sinkConnectorContext.getSinkConfig(); + + SinkConnectorConfig sinkConnectorConfig = sinkConfig.getSinkConnectorConfig(); + sinkConnectorConfig.validateSinkConfiguration(); + + imServiceHandler = create(sinkConnectorConfig); + } + + @Override + public void start() { + if (!started.compareAndSet(false, true)) { + log.info("LarkSinkConnector has been started."); + } + } + + @Override + public void commit(ConnectRecord record) { + // Sink does not need to implement + } + + @Override + public String name() { + return this.sinkConfig.getSinkConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + if (!started.compareAndSet(true, false)) { + log.info("LarkSinkConnector has not started yet."); + } + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + try { + if (Boolean.parseBoolean(sinkConfig.getSinkConnectorConfig().getSinkAsync())) { + imServiceHandler.sinkAsync(connectRecord); + } else { + imServiceHandler.sink(connectRecord); + } + } catch (ExecutionException | RetryException e) { + log.error("Failed to sink event to lark", e); + } + } + } + + @SneakyThrows + public static String getTenantAccessToken(String appId, String appSecret) { + return AUTH_CACHE.get(TENANT_ACCESS_TOKEN, () -> { + + Client client = Client.newBuilder(appId, appSecret) + .appType(AppType.SELF_BUILT) + .logReqAtDebug(true) + .build(); + + TenantAccessTokenResp resp = client.ext().getTenantAccessTokenBySelfBuiltApp( + SelfBuiltTenantAccessTokenReq.newBuilder() + .appSecret(appSecret) + .appId(appId) + .build()); + return resp.getTenantAccessToken(); + }); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-lark/src/main/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-lark/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..b5962fd99a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-LARK + idc: FT + env: PRD + group: larkSink + appId: 5031 + userName: larkSinkUser + passWord: larkPassWord +sinkConnectorConfig: + connectorName: larkSink + appId: appId + appSecret: appSecret + receiveIdType: open_id + receiveId: receiveId + sinkAsync: true + maxRetryTimes: 3 + retryDelayInMills: 1000 diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/test/java/org/apache/eventmesh/connector/lark/sink/ImServiceHandlerTest.java b/eventmesh-connectors/eventmesh-connector-lark/src/test/java/org/apache/eventmesh/connector/lark/sink/ImServiceHandlerTest.java new file mode 100644 index 0000000000..f72232a533 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/test/java/org/apache/eventmesh/connector/lark/sink/ImServiceHandlerTest.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.lark.sink; + +import static org.apache.eventmesh.connector.lark.sink.ImServiceHandler.create; +import static org.apache.eventmesh.connector.lark.sink.connector.LarkSinkConnector.AUTH_CACHE; +import static org.apache.eventmesh.connector.lark.sink.connector.LarkSinkConnector.TENANT_ACCESS_TOKEN; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.connector.lark.sink.config.LarkSinkConfig; +import org.apache.eventmesh.connector.lark.sink.config.SinkConnectorConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ReflectionSupport; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +import com.lark.oapi.service.im.v1.ImService; +import com.lark.oapi.service.im.v1.model.CreateMessageResp; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class ImServiceHandlerTest { + + private SinkConnectorConfig sinkConnectorConfig; + + private ImServiceHandler imServiceHandler; + + @Mock + private ImService imService; + + @Mock + private ImService.Message message; + + @BeforeEach + public void setup() throws Exception { + sinkConnectorConfig = ((LarkSinkConfig) ConfigUtil.parse(LarkSinkConfig.class)).getSinkConnectorConfig(); + } + + private void init() throws Exception { + // prevent rely on Lark's ExtService + AUTH_CACHE.put(TENANT_ACCESS_TOKEN, "test-TenantAccessToken"); + + imServiceHandler = create(sinkConnectorConfig); + + // prevent rely on Lark's ImService + when(message.create(any(), any())).thenReturn(new CreateMessageResp()); + when(imService.message()).thenReturn(message); + Field imServiceField = ReflectionSupport.findFields(imServiceHandler.getClass(), + (f) -> f.getName().equals("imService"), + HierarchyTraversalMode.BOTTOM_UP).get(0); + imServiceField.setAccessible(true); + imServiceField.set(imServiceHandler, imService); + } + + @Test + public void testRegularSink() throws Exception { + sinkConnectorConfig.setSinkAsync("false"); + init(); + regularSink(); + } + + @Test + public void testRegularSinkAsync() throws Exception { + sinkConnectorConfig.setSinkAsync("true"); + init(); + regularSink(); + } + + private void regularSink() throws Exception { + final int times = 3; + for (int i = 0; i < times; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, + System.currentTimeMillis(), "test-lark".getBytes(StandardCharsets.UTF_8)); + if (Boolean.parseBoolean(sinkConnectorConfig.getSinkAsync())) { + imServiceHandler.sinkAsync(connectRecord); + long retryDelayInMills = Long.parseLong(sinkConnectorConfig.getRetryDelayInMills()); + long duration = retryDelayInMills * times; + Thread.sleep(duration); + } else { + imServiceHandler.sink(connectRecord); + } + } + verify(message, times(times)).create(any(), any()); + } + + @Test + public void testRetrySink() throws Exception { + sinkConnectorConfig.setSinkAsync("false"); + init(); + retrySink(); + } + + @Test + public void testRetrySinkAsync() throws Exception { + sinkConnectorConfig.setSinkAsync("true"); + init(); + retrySink(); + } + + private void retrySink() throws Exception { + CreateMessageResp resp = new CreateMessageResp(); + resp.setCode(1); + doReturn(resp).when(message).create(any(), any()); + final int times = 3; + long retryDelayInMills = Long.parseLong(sinkConnectorConfig.getRetryDelayInMills()); + int maxRetryTimes = Integer.parseInt(sinkConnectorConfig.getMaxRetryTimes()); + // (maxRetryTimes + 1) event are actually sent + int sinkTimes = times * (maxRetryTimes + 1); + long duration = retryDelayInMills * sinkTimes; + + for (int i = 0; i < times; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, + System.currentTimeMillis(), "test-lark".getBytes(StandardCharsets.UTF_8)); + if (Boolean.parseBoolean(sinkConnectorConfig.getSinkAsync())) { + imServiceHandler.sinkAsync(connectRecord); + + Thread.sleep(duration); + } else { + Assertions.assertThrows(Exception.class, () -> imServiceHandler.sink(connectRecord)); + + } + } + verify(message, times(sinkTimes)).create(any(), any()); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/test/java/org/apache/eventmesh/connector/lark/sink/LarkSinkConnectorTest.java b/eventmesh-connectors/eventmesh-connector-lark/src/test/java/org/apache/eventmesh/connector/lark/sink/LarkSinkConnectorTest.java new file mode 100644 index 0000000000..658fa89223 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/test/java/org/apache/eventmesh/connector/lark/sink/LarkSinkConnectorTest.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.connector.lark.sink; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.apache.eventmesh.connector.lark.sink.config.LarkSinkConfig; +import org.apache.eventmesh.connector.lark.sink.connector.LarkSinkConnector; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class LarkSinkConnectorTest { + + private LarkSinkConnector larkSinkConnector; + + private LarkSinkConfig sinkConfig; + + /** + * more test see {@link ImServiceHandlerTest} + */ + @Mock + private ImServiceHandler imServiceHandler; + + private MockedStatic imServiceWrapperMockedStatic; + + @BeforeEach + public void setup() throws Exception { + imServiceWrapperMockedStatic = mockStatic(ImServiceHandler.class); + when(ImServiceHandler.create(any())).thenReturn(imServiceHandler); + doNothing().when(imServiceHandler).sink(any(ConnectRecord.class)); + doNothing().when(imServiceHandler).sinkAsync(any(ConnectRecord.class)); + + larkSinkConnector = new LarkSinkConnector(); + sinkConfig = (LarkSinkConfig) ConfigUtil.parse(larkSinkConnector.configClass()); + SinkConnectorContext sinkConnectorContext = new SinkConnectorContext(); + sinkConnectorContext.setSinkConfig(sinkConfig); + larkSinkConnector.init(sinkConnectorContext); + larkSinkConnector.start(); + } + + @Test + public void testPut() throws Exception { + final int times = 3; + List connectRecords = new ArrayList<>(); + for (int i = 0; i < times; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, + System.currentTimeMillis(), "test-lark".getBytes(StandardCharsets.UTF_8)); + connectRecords.add(connectRecord); + } + larkSinkConnector.put(connectRecords); + if (Boolean.parseBoolean(sinkConfig.getSinkConnectorConfig().getSinkAsync())) { + verify(imServiceHandler, times(times)).sinkAsync(any(ConnectRecord.class)); + } else { + verify(imServiceHandler, times(times)).sink(any(ConnectRecord.class)); + } + } + + @AfterEach + public void tearDown() { + LarkSinkConnector.AUTH_CACHE.invalidate(LarkSinkConnector.TENANT_ACCESS_TOKEN); + larkSinkConnector.stop(); + imServiceWrapperMockedStatic.close(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/test/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-lark/src/test/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/test/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-lark/src/test/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-lark/src/test/resources/sink-config.yml new file mode 100644 index 0000000000..b5962fd99a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-lark/src/test/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-LARK + idc: FT + env: PRD + group: larkSink + appId: 5031 + userName: larkSinkUser + passWord: larkPassWord +sinkConnectorConfig: + connectorName: larkSink + appId: appId + appSecret: appSecret + receiveIdType: open_id + receiveId: receiveId + sinkAsync: true + maxRetryTimes: 3 + retryDelayInMills: 1000 diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/build.gradle b/eventmesh-connectors/eventmesh-connector-mongodb/build.gradle new file mode 100644 index 0000000000..7c3dbb97b7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/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 { + implementation project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation project(":eventmesh-common") + + implementation 'org.mongodb:mongodb-driver:3.12.11' + + implementation 'io.cloudevents:cloudevents-json-jackson' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/gradle.properties b/eventmesh-connectors/eventmesh-connector-mongodb/gradle.properties new file mode 100644 index 0000000000..440c926cd3 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/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=mongodb \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/config/MongodbServerConfig.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/config/MongodbServerConfig.java new file mode 100644 index 0000000000..95c651b358 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/config/MongodbServerConfig.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.connector.mongodb.config; + +import lombok.Data; + +@Data +public class MongodbServerConfig { + + private boolean sourceEnable; + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/constant/MongodbConstants.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/constant/MongodbConstants.java new file mode 100644 index 0000000000..13dfbf530c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/constant/MongodbConstants.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.mongodb.constant; + +public class MongodbConstants { + + public static final String TOPIC = "flag"; + public static final String CAPPED_COL_TOPIC_FN = "topic"; + public static final String CAPPED_COL_CURSOR_FN = "ts"; + public static final String SEQUENCE_COLLECTION_NAME = "pub_sub_seq"; + public static final String SEQUENCE_KEY_FN = "topic"; + public static final String SEQUENCE_VALUE_FN = "value"; + public static final String CLOUD_EVENT_DOC_VERSION = "version"; + public static final String CLOUD_EVENT_DOC_DATA = "data"; + public static final String CLOUD_EVENT_DOC_ID = "id"; + public static final String CLOUD_EVENT_DOC_SOURCE = "source"; + public static final String CLOUD_EVENT_DOC_TYPE = "type"; + public static final String CLOUD_EVENT_DOC_DATACONTENTTYPE = "datacontenttype"; + public static final String CLOUD_EVENT_DOC_SUBJECT = "subject"; +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/server/MongodbConnectServer.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/server/MongodbConnectServer.java new file mode 100644 index 0000000000..4d58a35e16 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/server/MongodbConnectServer.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.connector.mongodb.server; + +import org.apache.eventmesh.connector.mongodb.config.MongodbServerConfig; +import org.apache.eventmesh.connector.mongodb.sink.connector.MongodbSinkConnector; +import org.apache.eventmesh.connector.mongodb.source.connector.MongodbSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +public class MongodbConnectServer { + + public static void main(String[] args) throws Exception { + + MongodbServerConfig serverConfig = ConfigUtil.parse(MongodbServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application mongodbSourceApp = new Application(); + mongodbSourceApp.run(MongodbSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application mongodbSinkApp = new Application(); + mongodbSinkApp.run(MongodbSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/client/Impl/MongodbSinkClient.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/client/Impl/MongodbSinkClient.java new file mode 100644 index 0000000000..dcc3bbe7b4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/client/Impl/MongodbSinkClient.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.mongodb.sink.client.Impl; + +import io.cloudevents.CloudEvent; + +/** + * MongodbSinkClient + */ +public interface MongodbSinkClient { + + void init(); + + void start(); + + void publish(CloudEvent cloudEvent); + + void stop(); + +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/client/MongodbReplicaSetSinkClient.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/client/MongodbReplicaSetSinkClient.java new file mode 100644 index 0000000000..638e1a7d3f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/client/MongodbReplicaSetSinkClient.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.connector.mongodb.sink.client; + +import org.apache.eventmesh.connector.mongodb.sink.client.Impl.MongodbSinkClient; +import org.apache.eventmesh.connector.mongodb.sink.config.SinkConnectorConfig; +import org.apache.eventmesh.connector.mongodb.utils.MongodbCloudEventUtil; + +import org.bson.Document; + +import io.cloudevents.CloudEvent; + +import com.mongodb.ConnectionString; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; + +public class MongodbReplicaSetSinkClient implements MongodbSinkClient { + + private final SinkConnectorConfig connectorConfig; + + private volatile boolean started = false; + + private MongoClient client; + + public MongodbReplicaSetSinkClient(SinkConnectorConfig connectorConfig) { + this.connectorConfig = connectorConfig; + } + + @Override + public void init() { + this.client = MongoClients.create(new ConnectionString(connectorConfig.getUrl())); + } + + @Override + public void start() { + if (!started) { + started = true; + } + } + + @Override + public void publish(CloudEvent cloudEvent) { + Document document = MongodbCloudEventUtil.convertToDocument(cloudEvent); + MongoCollection collection = client + .getDatabase(connectorConfig.getDatabase()).getCollection(connectorConfig.getCollection()); + collection.insertOne(document); + } + + @Override + public void stop() { + if (started) { + try { + this.client.close(); + } finally { + started = false; + } + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/client/MongodbStandaloneSinkClient.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/client/MongodbStandaloneSinkClient.java new file mode 100644 index 0000000000..45bdf6f699 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/client/MongodbStandaloneSinkClient.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.connector.mongodb.sink.client; + +import org.apache.eventmesh.connector.mongodb.constant.MongodbConstants; +import org.apache.eventmesh.connector.mongodb.sink.client.Impl.MongodbSinkClient; +import org.apache.eventmesh.connector.mongodb.sink.config.SinkConnectorConfig; +import org.apache.eventmesh.connector.mongodb.utils.MongodbCloudEventUtil; + +import org.bson.Document; + +import io.cloudevents.CloudEvent; + +import com.mongodb.BasicDBObject; +import com.mongodb.ConnectionString; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.FindOneAndUpdateOptions; +import com.mongodb.client.model.ReturnDocument; + +public class MongodbStandaloneSinkClient implements MongodbSinkClient { + + private final SinkConnectorConfig connectorConfig; + + private volatile boolean started = false; + + private MongoClient client; + + private MongoCollection cappedCol; + + private MongoCollection seqCol; + + public MongodbStandaloneSinkClient(SinkConnectorConfig connectorConfig) { + this.connectorConfig = connectorConfig; + } + + @Override + public void init() { + this.client = MongoClients.create(new ConnectionString(connectorConfig.getUrl())); + MongoDatabase db = client.getDatabase(connectorConfig.getDatabase()); + this.cappedCol = db.getCollection(connectorConfig.getCollection()); + this.seqCol = db.getCollection(MongodbConstants.SEQUENCE_COLLECTION_NAME); + } + + @Override + public void start() { + if (!started) { + started = true; + } + } + + @Override + public void publish(CloudEvent cloudEvent) { + Document doc = MongodbCloudEventUtil.convertToDocument(cloudEvent); + int i = getNextSeq(MongodbConstants.TOPIC); + doc.append(MongodbConstants.CAPPED_COL_TOPIC_FN, MongodbConstants.TOPIC) + .append(MongodbConstants.CAPPED_COL_CURSOR_FN, i); + cappedCol.insertOne(doc); + } + + @Override + public void stop() { + if (started) { + try { + this.client.close(); + } finally { + started = false; + } + } + } + + public int getNextSeq(String topic) { + Document query = new Document(MongodbConstants.SEQUENCE_KEY_FN, topic); + Document update = new Document("$inc", new BasicDBObject(MongodbConstants.SEQUENCE_VALUE_FN, 1)); + FindOneAndUpdateOptions options = new FindOneAndUpdateOptions(); + options.upsert(true); + options.returnDocument(ReturnDocument.AFTER); + Document result = seqCol.findOneAndUpdate(query, update, options); + return (int) (Integer) result.get(MongodbConstants.SEQUENCE_VALUE_FN); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/config/MongodbSinkConfig.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/config/MongodbSinkConfig.java new file mode 100644 index 0000000000..6df203bd6a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/config/MongodbSinkConfig.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.connector.mongodb.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; + +@Data +public class MongodbSinkConfig extends SinkConfig { + + public SinkConnectorConfig connectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..087b2e48ce --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/config/SinkConnectorConfig.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.connector.mongodb.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String connectorType; + + private String url; + + private String database; + + private String collection; +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/connector/MongodbSinkConnector.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/connector/MongodbSinkConnector.java new file mode 100644 index 0000000000..814aaf2882 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/sink/connector/MongodbSinkConnector.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.connector.mongodb.sink.connector; + +import org.apache.eventmesh.connector.mongodb.sink.client.Impl.MongodbSinkClient; +import org.apache.eventmesh.connector.mongodb.sink.client.MongodbReplicaSetSinkClient; +import org.apache.eventmesh.connector.mongodb.sink.client.MongodbStandaloneSinkClient; +import org.apache.eventmesh.connector.mongodb.sink.config.MongodbSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.List; + +import io.cloudevents.CloudEvent; + +import com.mongodb.connection.ClusterType; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MongodbSinkConnector implements Sink { + + private MongodbSinkConfig sinkConfig; + + private MongodbSinkClient client; + + @Override + public Class configClass() { + return MongodbSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + this.sinkConfig = (MongodbSinkConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (MongodbSinkConfig) sinkConnectorContext.getSinkConfig(); + doInit(); + } + + private void doInit() { + String connectorType = sinkConfig.getConnectorConfig().getConnectorType(); + if (connectorType.equals(ClusterType.STANDALONE.name())) { + this.client = new MongodbStandaloneSinkClient(sinkConfig.getConnectorConfig()); + } + if (connectorType.equals(ClusterType.REPLICA_SET.name())) { + this.client = new MongodbReplicaSetSinkClient(sinkConfig.getConnectorConfig()); + } + client.init(); + } + + @Override + public void start() throws Exception { + this.client.start(); + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() throws Exception { + this.client.stop(); + } + + @Override + public void put(List sinkRecords) { + try { + for (ConnectRecord connectRecord : sinkRecords) { + CloudEvent event = CloudEventUtil.convertRecordToEvent(connectRecord); + client.publish(event); + log.debug("Produced message to event:{}}", event); + } + } catch (Exception e) { + log.error("Failed to produce message:{}", e.getMessage()); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/client/Impl/MongodbSourceClient.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/client/Impl/MongodbSourceClient.java new file mode 100644 index 0000000000..f3dfd198a4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/client/Impl/MongodbSourceClient.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.connector.mongodb.source.client.Impl; + +/** + * MongodbSourceClient + */ +public interface MongodbSourceClient { + + void init(); + + void start(); + + void stop(); + +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/client/MongodbReplicaSetSourceClient.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/client/MongodbReplicaSetSourceClient.java new file mode 100644 index 0000000000..468cf6c92e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/client/MongodbReplicaSetSourceClient.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.connector.mongodb.source.client; + +import org.apache.eventmesh.connector.mongodb.source.client.Impl.MongodbSourceClient; +import org.apache.eventmesh.connector.mongodb.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.mongodb.utils.MongodbCloudEventUtil; + +import java.util.concurrent.BlockingQueue; + +import org.bson.Document; + +import io.cloudevents.CloudEvent; + +import com.mongodb.ConnectionString; +import com.mongodb.client.ChangeStreamIterable; +import com.mongodb.client.MongoChangeStreamCursor; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.model.changestream.ChangeStreamDocument; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MongodbReplicaSetSourceClient implements MongodbSourceClient { + + private final SourceConnectorConfig connectorConfig; + + private volatile boolean started = false; + + private MongoClient client; + + private MongoChangeStreamCursor> cursor; + + private final BlockingQueue queue; + + public MongodbReplicaSetSourceClient(SourceConnectorConfig connectorConfig, BlockingQueue queue) { + this.queue = queue; + this.connectorConfig = connectorConfig; + } + + @Override + public void init() { + this.client = MongoClients.create(new ConnectionString(connectorConfig.getUrl())); + } + + @Override + public void start() { + if (!started) { + MongoCollection collection = client + .getDatabase(connectorConfig.getDatabase()).getCollection(connectorConfig.getCollection()); + ChangeStreamIterable changeStreamDocuments = collection.watch(); + this.cursor = changeStreamDocuments.cursor(); + this.handle(); + started = true; + } + } + + @Override + public void stop() { + if (started) { + try { + this.client.close(); + this.cursor.close(); + } finally { + started = false; + } + } + } + + private void handle() { + while (this.cursor.hasNext()) { + ChangeStreamDocument next = cursor.next(); + Document fullDocument = next.getFullDocument(); + if (fullDocument != null) { + try { + CloudEvent cloudEvent = MongodbCloudEventUtil.convertToCloudEvent(fullDocument); + queue.add(cloudEvent); + } catch (Exception e) { + log.error("[MongodbReplicaSetSourceClient] happen exception.", e); + } + } + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/client/MongodbStandaloneSourceClient.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/client/MongodbStandaloneSourceClient.java new file mode 100644 index 0000000000..e062ab034d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/client/MongodbStandaloneSourceClient.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.connector.mongodb.source.client; + +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.connector.mongodb.constant.MongodbConstants; +import org.apache.eventmesh.connector.mongodb.source.client.Impl.MongodbSourceClient; +import org.apache.eventmesh.connector.mongodb.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.mongodb.utils.MongodbCloudEventUtil; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.bson.Document; + +import io.cloudevents.CloudEvent; + +import com.mongodb.ConnectionString; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MongodbStandaloneSourceClient implements MongodbSourceClient { + + private final SourceConnectorConfig connectorConfig; + + private volatile boolean started = false; + + private MongoClient client; + + private MongoCollection cappedCol; + + private final BlockingQueue queue; + + private final SubTask task = new SubTask(); + + private final ThreadPoolExecutor executor = ThreadPoolFactory.createThreadPoolExecutor( + Runtime.getRuntime().availableProcessors() * 2, + Runtime.getRuntime().availableProcessors() * 2, + "EventMesh-MongodbStandaloneSourceClient-"); + + public MongodbStandaloneSourceClient(SourceConnectorConfig connectorConfig, BlockingQueue queue) { + this.queue = queue; + this.connectorConfig = connectorConfig; + } + + @Override + public void init() { + this.client = MongoClients.create(new ConnectionString(connectorConfig.getUrl())); + MongoDatabase db = client.getDatabase(connectorConfig.getDatabase()); + this.cappedCol = db.getCollection(connectorConfig.getCollection()); + // create index + Document index = new Document(MongodbConstants.CAPPED_COL_CURSOR_FN, 1) + .append(MongodbConstants.CAPPED_COL_TOPIC_FN, 1); + this.cappedCol.createIndex(index); + } + + @Override + public void start() { + if (!started) { + executor.execute(task); + started = true; + } + } + + @Override + public void stop() { + if (started) { + try { + this.task.stop(); + this.client.close(); + } finally { + started = false; + } + } + } + + private FindIterable getCursor(MongoCollection collection, String topic, int lastId) { + Document index = new Document("$gt", lastId); + Document ts = new Document(MongodbConstants.CAPPED_COL_CURSOR_FN, index); + + Document spec = ts.append(MongodbConstants.CAPPED_COL_TOPIC_FN, topic); + return collection.find(spec); + } + + private class SubTask implements Runnable { + + private final AtomicBoolean stop = new AtomicBoolean(false); + + public void run() { + int lastId = -1; + while (!stop.get()) { + try { + FindIterable cur = getCursor(cappedCol, MongodbConstants.TOPIC, lastId); + for (Document obj : cur) { + CloudEvent cloudEvent = MongodbCloudEventUtil.convertToCloudEvent(obj); + queue.add(cloudEvent); + try { + lastId = (int) ((Double) obj.get(MongodbConstants.CAPPED_COL_CURSOR_FN)).doubleValue(); + } catch (ClassCastException ce) { + lastId = (Integer) obj.get(MongodbConstants.CAPPED_COL_CURSOR_FN); + } + } + } catch (Exception ex) { + log.error("[MongodbStandaloneSourceClient] thread run happen exception.", ex); + } + Thread.yield(); + } + } + + public void stop() { + stop.set(true); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/config/MongodbSourceConfig.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/config/MongodbSourceConfig.java new file mode 100644 index 0000000000..d67ad6c277 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/config/MongodbSourceConfig.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.connector.mongodb.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; + +@Data +public class MongodbSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..5c48645a43 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/config/SourceConnectorConfig.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.mongodb.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private String connectorType; + + private String url; + + private String database; + + private String collection; + +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/connector/MongodbSourceConnector.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/connector/MongodbSourceConnector.java new file mode 100644 index 0000000000..fec64de56c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/source/connector/MongodbSourceConnector.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.connector.mongodb.source.connector; + +import org.apache.eventmesh.connector.mongodb.source.client.Impl.MongodbSourceClient; +import org.apache.eventmesh.connector.mongodb.source.client.MongodbReplicaSetSourceClient; +import org.apache.eventmesh.connector.mongodb.source.client.MongodbStandaloneSourceClient; +import org.apache.eventmesh.connector.mongodb.source.config.MongodbSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import io.cloudevents.CloudEvent; + +import com.mongodb.connection.ClusterType; + +public class MongodbSourceConnector implements Source { + + private MongodbSourceConfig sourceConfig; + + private static final int DEFAULT_BATCH_SIZE = 10; + + private BlockingQueue queue; + + private MongodbSourceClient client; + + @Override + public Class configClass() { + return MongodbSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + this.sourceConfig = (MongodbSourceConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (MongodbSourceConfig) sourceConnectorContext.getSourceConfig(); + doInit(); + } + + private void doInit() { + this.queue = new LinkedBlockingQueue<>(1000); + String connectorType = sourceConfig.getConnectorConfig().getConnectorType(); + if (connectorType.equals(ClusterType.STANDALONE.name())) { + this.client = new MongodbStandaloneSourceClient(sourceConfig.getConnectorConfig(), queue); + } + if (connectorType.equals(ClusterType.REPLICA_SET.name())) { + this.client = new MongodbReplicaSetSourceClient(sourceConfig.getConnectorConfig(), queue); + } + client.init(); + } + + @Override + public void start() throws Exception { + this.client.start(); + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.connectorConfig.getConnectorName(); + } + + @Override + public void stop() throws Exception { + this.client.stop(); + } + + @Override + public List poll() { + List connectRecords = new ArrayList<>(DEFAULT_BATCH_SIZE); + for (int count = 0; count < DEFAULT_BATCH_SIZE; ++count) { + try { + CloudEvent event = queue.poll(3, TimeUnit.SECONDS); + if (event == null) { + break; + } + + connectRecords.add(CloudEventUtil.convertEventToRecord(event)); + } catch (InterruptedException e) { + break; + } + } + return connectRecords; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/utils/MongodbCloudEventUtil.java b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/utils/MongodbCloudEventUtil.java new file mode 100644 index 0000000000..ef2f34e6f4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/java/org/apache/eventmesh/connector/mongodb/utils/MongodbCloudEventUtil.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.connector.mongodb.utils; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.mongodb.constant.MongodbConstants; + +import java.net.URI; +import java.nio.charset.StandardCharsets; + +import org.bson.Document; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; + +public class MongodbCloudEventUtil { + + public static CloudEvent convertToCloudEvent(Document document) throws Exception { + document.remove("_id"); + String versionStr = document.getString(MongodbConstants.CLOUD_EVENT_DOC_VERSION); + SpecVersion version = SpecVersion.valueOf(versionStr); + CloudEventBuilder builder; + switch (version) { + case V03: + builder = CloudEventBuilder.v03(); + break; + case V1: + builder = CloudEventBuilder.v1(); + break; + default: + throw new Exception(String.format("CloudEvent version %s does not support.", version)); + } + builder.withData(document.remove(MongodbConstants.CLOUD_EVENT_DOC_DATA).toString().getBytes(Constants.DEFAULT_CHARSET)) + .withId(document.remove(MongodbConstants.CLOUD_EVENT_DOC_ID).toString()) + .withSource(URI.create(document.remove(MongodbConstants.CLOUD_EVENT_DOC_SOURCE).toString())) + .withType(document.remove(MongodbConstants.CLOUD_EVENT_DOC_TYPE).toString()) + .withDataContentType(document.remove(MongodbConstants.CLOUD_EVENT_DOC_DATACONTENTTYPE).toString()) + .withSubject(document.remove(MongodbConstants.CLOUD_EVENT_DOC_SUBJECT).toString()); + document.forEach((key, value) -> builder.withExtension(key, value.toString())); + + return builder.build(); + } + + public static Document convertToDocument(CloudEvent cloudEvent) { + Document document = new Document(); + document.put(MongodbConstants.CLOUD_EVENT_DOC_VERSION, cloudEvent.getSpecVersion().name()); + document.put(MongodbConstants.CLOUD_EVENT_DOC_DATA, cloudEvent.getData() == null + ? null + : new String(cloudEvent.getData().toBytes(), StandardCharsets.UTF_8)); + document.put(MongodbConstants.CLOUD_EVENT_DOC_ID, cloudEvent.getId()); + document.put(MongodbConstants.CLOUD_EVENT_DOC_SOURCE, cloudEvent.getSource().toString()); + document.put(MongodbConstants.CLOUD_EVENT_DOC_TYPE, cloudEvent.getType()); + document.put(MongodbConstants.CLOUD_EVENT_DOC_DATACONTENTTYPE, cloudEvent.getDataContentType()); + document.put(MongodbConstants.CLOUD_EVENT_DOC_SUBJECT, cloudEvent.getSubject()); + cloudEvent.getExtensionNames().forEach(key -> document.put(key, cloudEvent.getExtension(key))); + + return document; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..0f2ee2449b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: mongodbSink + appId: 5031 + userName: mongodbSinkUser + passWord: mongodbPassWord +connectorConfig: + connectorName: mongodbSink + connectorType: STANDALONE + #mongodb://root:root@127.0.0.1:27018,127.0.0.1:27019 + url: mongodb://127.0.0.1:27018 + database: db + collection: col + diff --git a/eventmesh-connectors/eventmesh-connector-mongodb/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/resources/source-config.yml new file mode 100644 index 0000000000..b4d264a058 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-mongodb/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: mongodbSource + appId: 5032 + userName: mongodbSourceUser + passWord: mongodbPassWord +connectorConfig: + connectorName: mongodbSource + connectorType: STANDALONE + #mongodb://root:root@127.0.0.1:27018,127.0.0.1:27019 + url: mongodb://127.0.0.1:27018 + database: db + collection: col +offsetStorageConfig: + offsetStorageType: nacos + offsetStorageAddr: 127.0.0.1:8848 + extensions: { + #same with connectorName + dataId: rocketmqSource, + #same with group + group: rocketmqSource + } \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/build.gradle b/eventmesh-connectors/eventmesh-connector-openfunction/build.gradle new file mode 100644 index 0000000000..5fc19090a7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/build.gradle @@ -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. + */ + +dependencies { + implementation project(":eventmesh-common") + implementation project(":eventmesh-sdks:eventmesh-sdk-java") + implementation project(":eventmesh-openconnect:eventmesh-openconnect-java") + + implementation "io.grpc:grpc-core" + implementation "io.grpc:grpc-protobuf" + implementation "io.grpc:grpc-stub" + implementation "io.grpc:grpc-netty" + implementation "io.grpc:grpc-netty-shaded" + + api "com.fasterxml.jackson.core:jackson-databind" + api "com.fasterxml.jackson.core:jackson-core" + api "com.fasterxml.jackson.core:jackson-annotations" + + implementation "javax.annotation:javax.annotation-api:1.3.2" + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/gradle.properties b/eventmesh-connectors/eventmesh-connector-openfunction/gradle.properties new file mode 100644 index 0000000000..cdcf52e5a8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/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=openfunction \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CallbackService.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CallbackService.java new file mode 100644 index 0000000000..2fda7c3293 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CallbackService.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.connector.openfunction.client; + +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; + +import io.grpc.stub.StreamObserver; + +import com.google.protobuf.Timestamp; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CallbackService extends CallbackServiceGrpc.CallbackServiceImplBase { + + @Override + public void onTopicEvent(CloudEvent cloudEvent, StreamObserver responseObserver) { + log.info("cloudevents: {}|data: {}", cloudEvent, cloudEvent.getTextData()); + + Instant instant = now(); + CloudEvent.Builder builder = CloudEvent.newBuilder(); + builder.putAttributes(ProtocolKey.GRPC_RESPONSE_CODE, + CloudEventAttributeValue.newBuilder().setCeString(StatusCode.SUCCESS.getRetCode()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_MESSAGE, + CloudEventAttributeValue.newBuilder().setCeString(StatusCode.SUCCESS.getErrMsg()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_TIME, CloudEventAttributeValue.newBuilder() + .setCeTimestamp(Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build()).build()); + responseObserver.onNext(builder.build()); + responseObserver.onCompleted(); + } + + private static Instant now() { + return OffsetDateTime.of(LocalDateTime.now(ZoneId.systemDefault()), ZoneOffset.UTC).toInstant(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CallbackServiceGrpc.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CallbackServiceGrpc.java new file mode 100644 index 0000000000..ddb2e650c2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CallbackServiceGrpc.java @@ -0,0 +1,270 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.openfunction.client; + +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; + +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; + +/** + * + */ +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.4.0)", + comments = "Source: callback-service.proto") +@io.grpc.stub.annotations.GrpcGenerated +public final class CallbackServiceGrpc { + + private CallbackServiceGrpc() { + } + + public static final String SERVICE_NAME = "org.apache.eventmesh.cloudevents.v1.CallbackService"; + + // Static method descriptors that strictly reflect the proto. + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901") + public static final io.grpc.MethodDescriptor METHOD_ON_TOPIC_EVENT = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName( + "org.apache.eventmesh.cloudevents.v1.CallbackService", "OnTopicEvent")) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + CloudEvent.getDefaultInstance())) + .build(); + + /** + * Creates a new async stub that supports all call types for the service + */ + public static CallbackServiceStub newStub(io.grpc.Channel channel) { + return new CallbackServiceStub(channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static CallbackServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + return new CallbackServiceBlockingStub(channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static CallbackServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + return new CallbackServiceFutureStub(channel); + } + + /** + * + */ + public static abstract class CallbackServiceImplBase implements io.grpc.BindableService { + + /** + *

+         * Subscribes events
+         * 
+ */ + public void onTopicEvent(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(METHOD_ON_TOPIC_EVENT, responseObserver); + } + + @Override + public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + METHOD_ON_TOPIC_EVENT, + asyncUnaryCall( + new MethodHandlers< + CloudEvent, + CloudEvent>( + this, METHODID_ON_TOPIC_EVENT))) + .build(); + } + } + + /** + * + */ + public static final class CallbackServiceStub extends io.grpc.stub.AbstractStub { + + private CallbackServiceStub(io.grpc.Channel channel) { + super(channel); + } + + private CallbackServiceStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected CallbackServiceStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new CallbackServiceStub(channel, callOptions); + } + + /** + *
+         * Subscribes events
+         * 
+ */ + public void onTopicEvent(CloudEvent request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(METHOD_ON_TOPIC_EVENT, getCallOptions()), request, responseObserver); + } + } + + /** + * + */ + public static final class CallbackServiceBlockingStub extends io.grpc.stub.AbstractStub { + + private CallbackServiceBlockingStub(io.grpc.Channel channel) { + super(channel); + } + + private CallbackServiceBlockingStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected CallbackServiceBlockingStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new CallbackServiceBlockingStub(channel, callOptions); + } + + /** + *
+         * Subscribes events
+         * 
+ */ + public CloudEvent onTopicEvent( + CloudEvent request) { + return blockingUnaryCall( + getChannel(), METHOD_ON_TOPIC_EVENT, getCallOptions(), request); + } + } + + /** + * + */ + public static final class CallbackServiceFutureStub extends io.grpc.stub.AbstractStub { + + private CallbackServiceFutureStub(io.grpc.Channel channel) { + super(channel); + } + + private CallbackServiceFutureStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @Override + protected CallbackServiceFutureStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new CallbackServiceFutureStub(channel, callOptions); + } + + /** + *
+         * Subscribes events
+         * 
+ */ + public com.google.common.util.concurrent.ListenableFuture onTopicEvent( + CloudEvent request) { + return futureUnaryCall( + getChannel().newCall(METHOD_ON_TOPIC_EVENT, getCallOptions()), request); + } + } + + private static final int METHODID_ON_TOPIC_EVENT = 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 CallbackServiceImplBase serviceImpl; + private final int methodId; + + MethodHandlers(CallbackServiceImplBase 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_ON_TOPIC_EVENT: + serviceImpl.onTopicEvent((CloudEvent) 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 final class CallbackServiceDescriptorSupplier implements io.grpc.protobuf.ProtoFileDescriptorSupplier { + + @Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return EventMeshGrpcService.getDescriptor(); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (CallbackServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new CallbackServiceDescriptorSupplier()) + .addMethod(METHOD_ON_TOPIC_EVENT) + .build(); + } + } + } + return result; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CloudEventsPublishInstance.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CloudEventsPublishInstance.java new file mode 100644 index 0000000000..578fd53397 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CloudEventsPublishInstance.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.openfunction.client; + +import static org.apache.eventmesh.common.Constants.CLOUD_EVENTS_PROTOCOL_NAME; + +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.utils.JsonUtils; +import org.apache.eventmesh.common.utils.ThreadUtils; + +import java.io.IOException; +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.TimeUnit; + +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 MESSAGE_SIZE = 5; + + public static void main(String[] args) throws Exception { + + try (EventMeshGrpcProducer eventMeshGrpcProducer = new EventMeshGrpcProducer( + initEventMeshGrpcClientConfig("FUNCTION_PRODUCER_GROUP"))) { + + final Map content = new HashMap<>(); + content.put("content", "testAsyncMessage"); + + for (int i = 0; i < MESSAGE_SIZE; i++) { + eventMeshGrpcProducer.publish(buildCloudEvent(content)); + ThreadUtils.sleep(1, TimeUnit.SECONDS); + } + + ThreadUtils.sleep(30, TimeUnit.SECONDS); + } + } + + protected static EventMeshGrpcClientConfig initEventMeshGrpcClientConfig(final String groupName) throws IOException { + final String eventMeshIp = "127.0.0.1"; + final String eventMeshGrpcPort = "10110"; + + return EventMeshGrpcClientConfig.builder() + .serverAddr(eventMeshIp) + .serverPort(Integer.parseInt(eventMeshGrpcPort)) + .producerGroup(groupName) + .env("env") + .idc("idc") + .sys("1234") + .build(); + } + + protected static CloudEvent buildCloudEvent(final Map content) { + return CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSubject("TEST-TOPIC-FUNCTION") + .withSource(URI.create("/")) + .withDataContentType("application/cloudevents+json") + .withType(CLOUD_EVENTS_PROTOCOL_NAME) + .withData(JsonUtils.toJSONString(content).getBytes(StandardCharsets.UTF_8)) + .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) + .build(); + + } +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CloudEventsSubscribeInstance.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CloudEventsSubscribeInstance.java new file mode 100644 index 0000000000..d1e5c5affd --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/CloudEventsSubscribeInstance.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.connector.openfunction.client; + +import io.grpc.Server; +import io.grpc.ServerBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CloudEventsSubscribeInstance { + + public static void main(String[] args) throws Exception { + Server server = ServerBuilder.forPort(10115).addService(new CallbackService()).build(); + server.start(); + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + server.shutdown(); + } catch (Exception e) { + log.error("exception when shutdown.", e); + } + })); + server.awaitTermination(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/EventMeshGrpcService.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/EventMeshGrpcService.java new file mode 100644 index 0000000000..b4c766e050 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/client/EventMeshGrpcService.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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: callback-service.proto + +package org.apache.eventmesh.connector.openfunction.client; + +public final class EventMeshGrpcService { + + private EventMeshGrpcService() { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + + static { + String[] descriptorData = { + "\n\026callback-service.proto\022#org.apache.eve" + + "ntmesh.cloudevents.v1\032\033eventmesh-cloudev" + + "ents.proto\032\031google/protobuf/any.proto\032\037g" + + "oogle/protobuf/timestamp.proto2\203\001\n\017Callb" + + "ackService\022p\n\014OnTopicEvent\022/.org.apache." + + "eventmesh.cloudevents.v1.CloudEvent\032/.or" + + "g.apache.eventmesh.cloudevents.v1.CloudE" + + "ventBA\n)org.apache.eventmesh.connect.ope" + + "nfunctionB\024EventMeshGrpcServiceb\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[] { + org.apache.eventmesh.common.protocol.grpc.cloudevents.EventMeshCloudEvents.getDescriptor(), + com.google.protobuf.AnyProto.getDescriptor(), + com.google.protobuf.TimestampProto.getDescriptor(), + }, assigner); + org.apache.eventmesh.common.protocol.grpc.cloudevents.EventMeshCloudEvents.getDescriptor(); + com.google.protobuf.AnyProto.getDescriptor(); + com.google.protobuf.TimestampProto.getDescriptor(); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/config/OpenFunctionServerConfig.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/config/OpenFunctionServerConfig.java new file mode 100644 index 0000000000..2cf28000f5 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/config/OpenFunctionServerConfig.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.openfunction.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class OpenFunctionServerConfig extends Config { + + private int serverPort; + + private boolean sourceEnable; + + private boolean sinkEnable; + + private String targetAddress; + + private int targetPort; + +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/server/OpenFunctionConnectServer.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/server/OpenFunctionConnectServer.java new file mode 100644 index 0000000000..18f5b604cc --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/server/OpenFunctionConnectServer.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.connector.openfunction.server; + +import org.apache.eventmesh.connector.openfunction.config.OpenFunctionServerConfig; +import org.apache.eventmesh.connector.openfunction.service.ConsumerService; +import org.apache.eventmesh.connector.openfunction.service.ProducerService; +import org.apache.eventmesh.connector.openfunction.sink.connector.OpenFunctionSinkConnector; +import org.apache.eventmesh.connector.openfunction.source.connector.OpenFunctionSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.api.connector.Connector; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.util.Map; + +import io.grpc.Server; +import io.grpc.ServerBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class OpenFunctionConnectServer { + + private static Server server; + + public static void main(String[] args) throws Exception { + + OpenFunctionServerConfig serverConfig = ConfigUtil.parse(OpenFunctionServerConfig.class, "server-config.yml"); + + int serverPort = serverConfig.getServerPort(); + + ServerBuilder grpcServerBuilder = ServerBuilder.forPort(serverPort); + + if (serverConfig.isSourceEnable()) { + Application openFunctionSourceApp = new Application(); + openFunctionSourceApp.run(OpenFunctionSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application openFunctionSinkApp = new Application(); + openFunctionSinkApp.run(OpenFunctionSinkConnector.class); + } + + Map connectorMap = Application.CONNECTOR_MAP; + + for (Map.Entry entry : connectorMap.entrySet()) { + if (Application.isSource(entry.getValue().getClass())) { + grpcServerBuilder.addService(new ProducerService((OpenFunctionSourceConnector) entry.getValue(), serverConfig)); + } else if (Application.isSink(entry.getValue().getClass())) { + grpcServerBuilder.addService(new ConsumerService((OpenFunctionSinkConnector) entry.getValue(), serverConfig)); + } + } + server = grpcServerBuilder.build(); + server.start(); + + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + server.shutdown(); + } catch (Exception e) { + log.error("exception when shutdown.", e); + } + })); + server.awaitTermination(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/service/ConsumerService.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/service/ConsumerService.java new file mode 100644 index 0000000000..8ed8a65b46 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/service/ConsumerService.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.connector.openfunction.service; + +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.Builder; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.ConsumerServiceGrpc; +import org.apache.eventmesh.connector.openfunction.client.CallbackServiceGrpc; +import org.apache.eventmesh.connector.openfunction.client.CallbackServiceGrpc.CallbackServiceBlockingStub; +import org.apache.eventmesh.connector.openfunction.config.OpenFunctionServerConfig; +import org.apache.eventmesh.connector.openfunction.sink.connector.OpenFunctionSinkConnector; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.commons.lang3.StringUtils; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import io.cloudevents.SpecVersion; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ConsumerService extends ConsumerServiceGrpc.ConsumerServiceImplBase { + + private final OpenFunctionSinkConnector openFunctionSinkConnector; + + private final BlockingQueue queue; + + private final CallbackServiceBlockingStub publisherClient; + + public ConsumerService(OpenFunctionSinkConnector openFunctionSinkConnector, OpenFunctionServerConfig serverConfig) { + this.openFunctionSinkConnector = openFunctionSinkConnector; + this.queue = openFunctionSinkConnector.queue(); + ManagedChannel channel = ManagedChannelBuilder.forAddress(serverConfig.getTargetAddress(), + serverConfig.getTargetPort()).usePlaintext().build(); + this.publisherClient = CallbackServiceGrpc.newBlockingStub(channel); + ExecutorService handleService = Executors.newSingleThreadExecutor(); + handleService.execute(this::startHandleConsumeEvents); + } + + private void startHandleConsumeEvents() { + while (openFunctionSinkConnector.isRunning()) { + ConnectRecord connectRecord = queue.poll(); + if (connectRecord != null) { + CloudEvent response = publisherClient.onTopicEvent(convertRecordToEvent(connectRecord)); + } + } + + } + + private CloudEvent convertRecordToEvent(ConnectRecord connectRecord) { + Builder cloudEventBuilder = CloudEvent.newBuilder(); + cloudEventBuilder.setId(connectRecord.getExtension("id")); + cloudEventBuilder.setSource(connectRecord.getExtension("source")); + cloudEventBuilder.setSpecVersion(SpecVersion.V1.toString()); + cloudEventBuilder.setType(connectRecord.getExtension("type")); + cloudEventBuilder.setTextData(new String((byte[]) connectRecord.getData())); + for (String extensionKey : connectRecord.getExtensions().keySet()) { + if (!StringUtils.equalsAny(extensionKey, "id", "source", "type")) { + cloudEventBuilder.putAttributes(extensionKey, + CloudEventAttributeValue.newBuilder().setCeString(connectRecord.getExtension(extensionKey)).build()); + } + } + return cloudEventBuilder.build(); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/service/ProducerService.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/service/ProducerService.java new file mode 100644 index 0000000000..df746e2ff8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/service/ProducerService.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.connector.openfunction.service; + +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.PublisherServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.connector.openfunction.config.OpenFunctionServerConfig; +import org.apache.eventmesh.connector.openfunction.source.connector.OpenFunctionSourceConnector; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.Objects; +import java.util.concurrent.BlockingQueue; + +import io.grpc.stub.StreamObserver; + +import com.google.protobuf.Timestamp; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ProducerService extends PublisherServiceGrpc.PublisherServiceImplBase { + + private final OpenFunctionSourceConnector openFunctionSourceConnector; + + private final BlockingQueue queue; + + private final OpenFunctionServerConfig config; + + public ProducerService(OpenFunctionSourceConnector openFunctionSourceConnector, OpenFunctionServerConfig serverConfig) { + this.openFunctionSourceConnector = openFunctionSourceConnector; + this.queue = openFunctionSourceConnector.queue(); + this.config = serverConfig; + } + + /** + * publish event to eventmesh + * + * @param event + * @param responseObserver + */ + @Override + public void publish(CloudEvent event, StreamObserver responseObserver) { + log.info("receive cloudevents {}", event); + Instant instant = now(); + CloudEvent.Builder builder = CloudEvent.newBuilder(); + ConnectRecord connectRecord = convertCloudEventToConnectorRecord(event); + try { + // put record to source connector + queue.put(connectRecord); + builder.putAttributes(ProtocolKey.GRPC_RESPONSE_CODE, + CloudEventAttributeValue.newBuilder().setCeString(StatusCode.SUCCESS.getRetCode()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_MESSAGE, + CloudEventAttributeValue.newBuilder().setCeString(StatusCode.SUCCESS.getErrMsg()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_TIME, CloudEventAttributeValue.newBuilder() + .setCeTimestamp(Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build()).build()); + } catch (InterruptedException e) { + log.error("publish event error {}", e.getMessage()); + builder.putAttributes(ProtocolKey.GRPC_RESPONSE_CODE, + CloudEventAttributeValue.newBuilder().setCeString(StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_MESSAGE, + CloudEventAttributeValue.newBuilder().setCeString(StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_TIME, CloudEventAttributeValue.newBuilder() + .setCeTimestamp(Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build()).build()); + Thread.currentThread().interrupt(); + } + + responseObserver.onNext(builder.build()); + responseObserver.onCompleted(); + + } + + private ConnectRecord convertCloudEventToConnectorRecord(CloudEvent event) { + ConnectRecord connectRecord = new ConnectRecord(null, null, System.currentTimeMillis(), event.getTextData()); + for (String extensionName : event.getAttributesMap().keySet()) { + connectRecord.addExtension(extensionName, Objects.requireNonNull(event.getAttributesOrThrow(extensionName)).getCeString()); + } + connectRecord.addExtension("id", event.getId()); + connectRecord.addExtension("source", event.getSource()); + connectRecord.addExtension("type", event.getType()); + return connectRecord; + } + + /** + * publish eventBatch to eventmesh + * + * @param eventBatch + * @param responseObserver + */ + @Override + public void batchPublish(CloudEventBatch eventBatch, StreamObserver responseObserver) { + + } + + private static Instant now() { + return OffsetDateTime.of(LocalDateTime.now(ZoneId.systemDefault()), ZoneOffset.UTC).toInstant(); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/sink/config/OpenFunctionSinkConfig.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/sink/config/OpenFunctionSinkConfig.java new file mode 100644 index 0000000000..6e4fbe3dc4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/sink/config/OpenFunctionSinkConfig.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.connector.openfunction.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class OpenFunctionSinkConfig extends SinkConfig { + + public SinkConnectorConfig sinkConnectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..77c1b7c701 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/sink/config/SinkConnectorConfig.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.connector.openfunction.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String target; +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/sink/connector/OpenFunctionSinkConnector.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/sink/connector/OpenFunctionSinkConnector.java new file mode 100644 index 0000000000..aed6936004 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/sink/connector/OpenFunctionSinkConnector.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.connector.openfunction.sink.connector; + +import org.apache.eventmesh.connector.openfunction.sink.config.OpenFunctionSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class OpenFunctionSinkConnector implements Sink { + + private OpenFunctionSinkConfig sinkConfig; + + private BlockingQueue queue; + + private volatile boolean isRunning = false; + + @Override + public Class configClass() { + return OpenFunctionSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for openfunction source connector + this.sinkConfig = (OpenFunctionSinkConfig) config; + this.queue = new LinkedBlockingQueue<>(1000); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + // init config for openfunction source connector + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (OpenFunctionSinkConfig) sinkConnectorContext.getSinkConfig(); + this.queue = new LinkedBlockingQueue<>(1000); + } + + @Override + public void start() throws Exception { + isRunning = true; + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getSinkConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + try { + queue.put(connectRecord); + } catch (InterruptedException e) { + Thread currentThread = Thread.currentThread(); + log.warn("[OpenFunctionSinkConnector] Interrupting thread {} due to exception {}", + currentThread.getName(), e.getMessage()); + currentThread.interrupt(); + } + } + } + + public BlockingQueue queue() { + return queue; + } + + public boolean isRunning() { + return isRunning; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/source/config/OpenFunctionSourceConfig.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/source/config/OpenFunctionSourceConfig.java new file mode 100644 index 0000000000..f3f5b52756 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/source/config/OpenFunctionSourceConfig.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.connector.openfunction.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class OpenFunctionSourceConfig extends SourceConfig { + + public SourceConnectorConfig sourceConnectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..93fc9739fc --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/source/config/SourceConnectorConfig.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.openfunction.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/source/connector/OpenFunctionSourceConnector.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/source/connector/OpenFunctionSourceConnector.java new file mode 100644 index 0000000000..916d6793db --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/java/org/apache/eventmesh/connector/openfunction/source/connector/OpenFunctionSourceConnector.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.connector.openfunction.source.connector; + +import org.apache.eventmesh.connector.openfunction.source.config.OpenFunctionSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class OpenFunctionSourceConnector implements Source { + + private static final int DEFAULT_BATCH_SIZE = 10; + + private OpenFunctionSourceConfig sourceConfig; + + private BlockingQueue queue; + + @Override + public Class configClass() { + return OpenFunctionSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for openfunction source connector + this.sourceConfig = (OpenFunctionSourceConfig) config; + this.queue = new LinkedBlockingQueue<>(1000); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + // init config for openfunction source connector + this.sourceConfig = (OpenFunctionSourceConfig) sourceConnectorContext.getSourceConfig(); + this.queue = new LinkedBlockingQueue<>(1000); + } + + @Override + public void start() throws Exception { + + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.getSourceConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + + } + + public BlockingQueue queue() { + return queue; + } + + @Override + public List poll() { + + List connectRecords = new ArrayList<>(DEFAULT_BATCH_SIZE); + + for (int count = 0; count < DEFAULT_BATCH_SIZE; ++count) { + try { + ConnectRecord connectRecord = queue.poll(3, TimeUnit.SECONDS); + if (connectRecord == null) { + break; + } + connectRecords.add(connectRecord); + } catch (InterruptedException e) { + Thread currentThread = Thread.currentThread(); + log.warn("[OpenFunctionSourceConnector] Interrupting thread {} due to exception {}", + currentThread.getName(), e.getMessage()); + currentThread.interrupt(); + } + } + return connectRecords; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/proto/callback-service.proto b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/proto/callback-service.proto new file mode 100644 index 0000000000..b7e21d054f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/proto/callback-service.proto @@ -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. + */ + +syntax = "proto3"; + +package org.apache.eventmesh.cloudevents.v1; + +import "eventmesh-cloudevents.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; + +option java_outer_classname = "EventMeshGrpcService"; +option java_package = "org.apache.eventmesh.connect.openfunction"; + +service CallbackService { + + // Subscribes events + rpc OnTopicEvent(CloudEvent) returns (CloudEvent); + +} + + + diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/proto/eventmesh-cloudevents.proto b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/proto/eventmesh-cloudevents.proto new file mode 100644 index 0000000000..37e07a0b40 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/proto/eventmesh-cloudevents.proto @@ -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. + */ + + + +/** + * CloudEvent Protobuf Format + * + * - Required context attributes are explicitly represented. + * - Optional and Extension context attributes are carried in a map structure. + * - Data may be represented as binary, text, or protobuf messages. + */ + +syntax = "proto3"; + +package org.apache.eventmesh.cloudevents.v1; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; + +option java_package = "org.apache.eventmesh.common.protocol.grpc.cloudevents"; +option java_multiple_files = true; +option java_outer_classname = "EventMeshCloudEvents"; + + +message CloudEvent { + + // -- CloudEvent Context Attributes + + // Required Attributes + string id = 1; + string source = 2; // URI-reference + string spec_version = 3; + string type = 4; + + // Optional & Extension Attributes + map attributes = 5; + + // -- CloudEvent Data (Bytes, Text, or Proto) + oneof data { + bytes binary_data = 6; + string text_data = 7; + google.protobuf.Any proto_data = 8; + } + + /** + * The CloudEvent specification defines + * seven attribute value types... + */ + + message CloudEventAttributeValue { + + oneof attr { + bool ce_boolean = 1; + int32 ce_integer = 2; + string ce_string = 3; + bytes ce_bytes = 4; + string ce_uri = 5; + string ce_uri_ref = 6; + google.protobuf.Timestamp ce_timestamp = 7; + } + } +} + +/** + * CloudEvent Protobuf Batch Format + * + */ + +message CloudEventBatch { + repeated CloudEvent events = 1; +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/proto/eventmesh-service.proto b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/proto/eventmesh-service.proto new file mode 100644 index 0000000000..99d57bc514 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/proto/eventmesh-service.proto @@ -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. + */ +syntax = "proto3"; + +package org.apache.eventmesh.cloudevents.v1; + +import "google/protobuf/empty.proto"; +import "eventmesh-cloudevents.proto"; + +option java_package = "org.apache.eventmesh.common.protocol.grpc.cloudevents"; +option java_multiple_files = true; +option java_outer_classname = "EventMeshGrpcService"; + + +service PublisherService { + //publish event + rpc publish(CloudEvent) returns (CloudEvent); + + //publish event with reply + rpc requestReply(CloudEvent) returns (CloudEvent); + + //publish event one way + rpc publishOneWay(CloudEvent) returns (google.protobuf.Empty); + + // publish batch event + rpc batchPublish(CloudEventBatch) returns (CloudEvent); + + //publish batch event one way + rpc batchPublishOneWay(CloudEventBatch) returns (google.protobuf.Empty); +} + +service ConsumerService { + // The subscribed event will be delivered by invoking the webhook url in the Subscription + rpc subscribe(CloudEvent) returns (CloudEvent); + + // The subscribed event will be delivered through stream of Message + rpc subscribeStream(stream CloudEvent) returns (stream CloudEvent); + + rpc unsubscribe(CloudEvent) returns (CloudEvent); +} + +service HeartbeatService { + rpc heartbeat(CloudEvent) returns (CloudEvent); +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/resources/server-config.yml new file mode 100644 index 0000000000..83c94d164b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/resources/server-config.yml @@ -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. +# + +serverPort: 10110 +sourceEnable: true +sinkEnable: true +targetAddress: 127.0.0.1 +targetPort: 10115 diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..659ed04920 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-FUNCTION + idc: FT + env: PRD + group: openFunctionSink + appId: 5031 + userName: openFunctionSinkUser + passWord: openFunctionPassWord +sinkConnectorConfig: + connectorName: openFunctionSink + target: 127.0.0.1:8080/openfunction diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/resources/source-config.yml new file mode 100644 index 0000000000..1b75dcab42 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-FUNCTION + idc: FT + env: PRD + group: openFunctionSource + appId: 5031 + userName: openFunctionSourceUser + passWord: openFunctionPassWord +sourceConnectorConfig: + connectorName: openFunctionSource diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/test/java/org/apache/eventmesh/connector/openfunction/sink/connector/OpenFunctionSinkConnectorTest.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/test/java/org/apache/eventmesh/connector/openfunction/sink/connector/OpenFunctionSinkConnectorTest.java new file mode 100644 index 0000000000..efb25b8ea9 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/test/java/org/apache/eventmesh/connector/openfunction/sink/connector/OpenFunctionSinkConnectorTest.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.connector.openfunction.sink.connector; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.apache.eventmesh.connector.openfunction.sink.config.OpenFunctionSinkConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class OpenFunctionSinkConnectorTest { + + private final OpenFunctionSinkConnector connector = new OpenFunctionSinkConnector(); + + @BeforeEach + public void setUp() throws Exception { + OpenFunctionSinkConfig sinkConfig = new OpenFunctionSinkConfig(); + connector.init(sinkConfig); + connector.start(); + } + + @Test + public void testSinkConnectorRunning() { + Assertions.assertTrue(connector.isRunning()); + } + + @Test + public void testOpenFunctionSinkConnector() throws Exception { + final int count = 5; + final String message = "testMessage"; + writeMockedRecords(count, message); + BlockingQueue queue = connector.queue(); + Assertions.assertEquals(count, queue.size()); + for (int i = 0; i < count; i++) { + ConnectRecord poll = queue.poll(); + assertNotNull(poll); + String expectedMessage = message + i; + Assertions.assertEquals(poll.getData(), expectedMessage); + } + } + + @AfterEach + public void shutdownConnector() { + connector.stop(); + } + + private void writeMockedRecords(int count, String message) throws Exception { + List records = new ArrayList<>(); + for (int i = 0; i < count; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + records.add(new ConnectRecord(partition, offset, System.currentTimeMillis(), message + i)); + } + connector.put(records); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-openfunction/src/test/java/org/apache/eventmesh/connector/openfunction/source/connector/OpenFunctionSourceConnectorTest.java b/eventmesh-connectors/eventmesh-connector-openfunction/src/test/java/org/apache/eventmesh/connector/openfunction/source/connector/OpenFunctionSourceConnectorTest.java new file mode 100644 index 0000000000..2663443dbe --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-openfunction/src/test/java/org/apache/eventmesh/connector/openfunction/source/connector/OpenFunctionSourceConnectorTest.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.connector.openfunction.source.connector; + +import org.apache.eventmesh.connector.openfunction.source.config.OpenFunctionSourceConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.List; +import java.util.concurrent.BlockingQueue; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class OpenFunctionSourceConnectorTest { + + private final OpenFunctionSourceConnector connector = new OpenFunctionSourceConnector(); + + @Test + public void testSpringSourceConnector() throws Exception { + OpenFunctionSourceConfig sourceConfig = new OpenFunctionSourceConfig(); + connector.init(sourceConfig); + connector.start(); + final int count = 5; + final String message = "testMessage"; + writeMockedRecords(count, message); + List connectRecords = connector.poll(); + Assertions.assertEquals(count, connectRecords.size()); + for (int i = 0; i < connectRecords.size(); i++) { + Object actualMessage = String.valueOf(connectRecords.get(i).getData()); + String expectedMessage = "testMessage" + i; + Assertions.assertEquals(expectedMessage, actualMessage); + } + connector.stop(); + } + + private void writeMockedRecords(int count, String message) { + BlockingQueue queue = connector.queue(); + for (int i = 0; i < count; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord record = new ConnectRecord(partition, offset, System.currentTimeMillis(), message + i); + queue.offer(record); + } + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/build.gradle b/eventmesh-connectors/eventmesh-connector-pravega/build.gradle new file mode 100644 index 0000000000..0365334311 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/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. + */ + +configurations { + implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' + implementation.exclude group: 'log4j', module: 'log4j' +} + +dependencies { + api project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation project(":eventmesh-common") + + implementation("io.pravega:pravega-client:$pravega_version") + + implementation 'io.cloudevents:cloudevents-json-jackson' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/gradle.properties b/eventmesh-connectors/eventmesh-connector-pravega/gradle.properties new file mode 100644 index 0000000000..a5ea881f6f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/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. +# + +pravega_version=0.11.0 + +pluginType=connector +pluginName=pravega \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/PravegaCloudEventWriter.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/client/PravegaCloudEventWriter.java similarity index 97% rename from eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/PravegaCloudEventWriter.java rename to eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/client/PravegaCloudEventWriter.java index 25c59edea5..e8f6e5cba5 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/PravegaCloudEventWriter.java +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/client/PravegaCloudEventWriter.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.storage.pravega.client; +package org.apache.eventmesh.connector.pravega.client; import java.nio.charset.StandardCharsets; diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/PravegaEvent.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/client/PravegaEvent.java similarity index 81% rename from eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/PravegaEvent.java rename to eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/client/PravegaEvent.java index 4ae85de928..ce06e482e7 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/PravegaEvent.java +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/client/PravegaEvent.java @@ -15,10 +15,9 @@ * limitations under the License. */ -package org.apache.eventmesh.storage.pravega.client; +package org.apache.eventmesh.connector.pravega.client; import org.apache.eventmesh.common.utils.JsonUtils; -import org.apache.eventmesh.storage.pravega.exception.PravegaStorageException; import java.io.Serializable; import java.net.URI; @@ -54,17 +53,7 @@ public static PravegaEvent getFromByteArray(byte[] body) { } public CloudEvent convertToCloudEvent() { - CloudEventBuilder builder; - switch (version) { - case V03: - builder = CloudEventBuilder.v03(); - break; - case V1: - builder = CloudEventBuilder.v1(); - break; - default: - throw new PravegaStorageException(String.format("CloudEvent version %s does not support.", version)); - } + CloudEventBuilder builder = CloudEventBuilder.fromSpecVersion(version); builder.withData(data.getBytes(StandardCharsets.UTF_8)) .withId(extensions.remove("id")) .withSource(URI.create(extensions.remove("source"))) diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/config/PravegaServerConfig.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/config/PravegaServerConfig.java new file mode 100644 index 0000000000..bf5d9a4fb7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/config/PravegaServerConfig.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.pravega.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class PravegaServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/exception/PravegaConnectorException.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/exception/PravegaConnectorException.java new file mode 100644 index 0000000000..5a94f3a871 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/exception/PravegaConnectorException.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.pravega.exception; + +public class PravegaConnectorException extends Exception { + + public PravegaConnectorException(String message) { + super(message); + } + + public PravegaConnectorException(Throwable throwable) { + super(throwable); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/server/PravegaConnectServer.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/server/PravegaConnectServer.java new file mode 100644 index 0000000000..7501396162 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/server/PravegaConnectServer.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.pravega.server; + +import org.apache.eventmesh.connector.pravega.config.PravegaServerConfig; +import org.apache.eventmesh.connector.pravega.sink.connector.PravegaSinkConnector; +import org.apache.eventmesh.connector.pravega.source.connector.PravegaSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PravegaConnectServer { + + public static void main(String[] args) throws Exception { + + PravegaServerConfig serverConfig = ConfigUtil.parse(PravegaServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application pravegaSourceApp = new Application(); + pravegaSourceApp.run(PravegaSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application pravegaSinkApp = new Application(); + pravegaSinkApp.run(PravegaSinkConnector.class); + } + + } +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/sink/config/PravegaSinkConfig.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/sink/config/PravegaSinkConfig.java new file mode 100644 index 0000000000..739c6539b5 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/sink/config/PravegaSinkConfig.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.connector.pravega.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class PravegaSinkConfig extends SinkConfig { + + public SinkConnectorConfig connectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..c254dee3b8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/sink/config/SinkConnectorConfig.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.pravega.sink.config; + +import java.net.URI; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private URI controllerURI; + + private String scope; + + private int clientPoolSize; + + private int queueSize; + + private boolean authEnabled; + + private String username; + + private String password; + + private boolean tlsEnable; + + private String truststore; +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/sink/connector/PravegaSinkConnector.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/sink/connector/PravegaSinkConnector.java new file mode 100644 index 0000000000..d1d29ad95d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/sink/connector/PravegaSinkConnector.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.connector.pravega.sink.connector; + +import org.apache.eventmesh.connector.pravega.client.PravegaCloudEventWriter; +import org.apache.eventmesh.connector.pravega.client.PravegaEvent; +import org.apache.eventmesh.connector.pravega.exception.PravegaConnectorException; +import org.apache.eventmesh.connector.pravega.sink.config.PravegaSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.cloudevents.CloudEvent; +import io.pravega.client.ClientConfig; +import io.pravega.client.EventStreamClientFactory; +import io.pravega.client.admin.StreamManager; +import io.pravega.client.stream.EventStreamWriter; +import io.pravega.client.stream.EventWriterConfig; +import io.pravega.client.stream.StreamConfiguration; +import io.pravega.client.stream.impl.ByteArraySerializer; +import io.pravega.shared.security.auth.DefaultCredentials; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PravegaSinkConnector implements Sink { + + private PravegaSinkConfig sinkConfig; + private StreamManager streamManager; + private EventStreamClientFactory clientFactory; + private final Map> writerMap = new ConcurrentHashMap<>(); + + private static final AtomicBoolean started = new AtomicBoolean(false); + + @Override + public Class configClass() { + return PravegaSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (PravegaSinkConfig) sinkConnectorContext.getSinkConfig(); + + streamManager = StreamManager.create(sinkConfig.getConnectorConfig().getControllerURI()); + + if (!streamManager.checkScopeExists(sinkConfig.getConnectorConfig().getScope())) { + streamManager.createScope(sinkConfig.getConnectorConfig().getScope()); + log.debug("scope[{}] is just created.", sinkConfig.getConnectorConfig().getScope()); + } + + ClientConfig.ClientConfigBuilder clientConfigBuilder = + ClientConfig.builder().controllerURI(sinkConfig.getConnectorConfig().getControllerURI()); + if (sinkConfig.getConnectorConfig().isAuthEnabled()) { + clientConfigBuilder.credentials( + new DefaultCredentials( + sinkConfig.getConnectorConfig().getPassword(), + sinkConfig.getConnectorConfig().getUsername())); + } + if (sinkConfig.getConnectorConfig().isTlsEnable()) { + clientConfigBuilder.trustStore(sinkConfig.getConnectorConfig().getTruststore()).validateHostName(false); + } + ClientConfig clientConfig = clientConfigBuilder.build(); + clientFactory = EventStreamClientFactory.withScope(sinkConfig.getConnectorConfig().getScope(), clientConfig); + } + + @Override + public void start() throws Exception { + started.compareAndSet(false, true); + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + writerMap.forEach((topic, writer) -> writer.close()); + writerMap.clear(); + clientFactory.close(); + streamManager.close(); + started.compareAndSet(true, false); + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + CloudEvent cloudEvent = CloudEventUtil.convertRecordToEvent(connectRecord); + try { + publish(cloudEvent.getSubject(), cloudEvent); + } catch (InterruptedException e) { + Thread currentThread = Thread.currentThread(); + log.warn("[PravegaSinkConnector] Interrupting thread {} due to exception {}", currentThread.getName(), e.getMessage()); + currentThread.interrupt(); + } catch (Exception e) { + log.error("[PravegaSinkConnector] sendResult has error : ", e); + } + } + } + + private void publish(String topic, CloudEvent cloudEvent) throws Exception { + if (!createStream(topic)) { + log.debug("stream[{}] has already been created.", topic); + } + + try (EventStreamWriter writer = writerMap.computeIfAbsent(topic, + k -> clientFactory.createEventWriter(topic, new ByteArraySerializer(), EventWriterConfig.builder().build()))) { + PravegaCloudEventWriter cloudEventWriter = new PravegaCloudEventWriter(topic); + PravegaEvent pravegaEvent = cloudEventWriter.writeBinary(cloudEvent); + writer.writeEvent(PravegaEvent.toByteArray(pravegaEvent)).get(5, TimeUnit.SECONDS); + } catch (ExecutionException | InterruptedException | TimeoutException e) { + log.error(String.format("Write topic[%s] fail.", topic), e); + throw new PravegaConnectorException(String.format("Write topic[%s] fail.", topic)); + } + } + + private boolean createStream(String topic) { + StreamConfiguration streamConfiguration = StreamConfiguration.builder().build(); + return streamManager.createStream(sinkConfig.getConnectorConfig().getScope(), topic, streamConfiguration); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/source/config/PravegaSourceConfig.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/source/config/PravegaSourceConfig.java new file mode 100644 index 0000000000..87fbd3d573 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/source/config/PravegaSourceConfig.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.connector.pravega.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class PravegaSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..1ff54d1c1c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/source/config/SourceConnectorConfig.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.connector.pravega.source.config; + +import java.net.URI; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private URI controllerURI; + + private String scope; + + private int clientPoolSize; + + private int queueSize; + + private boolean authEnabled; + + private String username; + + private String password; + + private boolean tlsEnable; + + private String truststore; + +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/source/connector/PravegaSourceConnector.java b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/source/connector/PravegaSourceConnector.java new file mode 100644 index 0000000000..c72c38f71d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/java/org/apache/eventmesh/connector/pravega/source/connector/PravegaSourceConnector.java @@ -0,0 +1,215 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.pravega.source.connector; + +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.connector.pravega.client.PravegaEvent; +import org.apache.eventmesh.connector.pravega.source.config.PravegaSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.cloudevents.CloudEvent; +import io.pravega.client.ClientConfig; +import io.pravega.client.EventStreamClientFactory; +import io.pravega.client.admin.ReaderGroupManager; +import io.pravega.client.admin.StreamManager; +import io.pravega.client.stream.EventRead; +import io.pravega.client.stream.EventStreamReader; +import io.pravega.client.stream.ReaderConfig; +import io.pravega.client.stream.ReaderGroupConfig; +import io.pravega.client.stream.impl.ByteArraySerializer; +import io.pravega.shared.NameUtils; +import io.pravega.shared.security.auth.DefaultCredentials; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PravegaSourceConnector implements Source { + + private static final AtomicBoolean started = new AtomicBoolean(false); + + private static final int DEFAULT_BATCH_SIZE = 10; + + private PravegaSourceConfig sourceConfig; + + private StreamManager streamManager; + + private EventStreamClientFactory clientFactory; + + private ReaderGroupManager readerGroupManager; + + private final Map sourceHandlerMap = new ConcurrentHashMap<>(); + + private BlockingQueue queue; + + private final ThreadPoolExecutor executor = ThreadPoolFactory.createThreadPoolExecutor( + Runtime.getRuntime().availableProcessors() * 2, + Runtime.getRuntime().availableProcessors() * 2, + "EventMesh-RabbitMQSourceConnector-"); + + @Override + public Class configClass() { + return PravegaSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (PravegaSourceConfig) sourceConnectorContext.getSourceConfig(); + this.queue = new LinkedBlockingQueue<>(1000); + + streamManager = StreamManager.create(sourceConfig.getConnectorConfig().getControllerURI()); + ClientConfig.ClientConfigBuilder clientConfigBuilder = + ClientConfig.builder().controllerURI(sourceConfig.getConnectorConfig().getControllerURI()); + if (sourceConfig.getConnectorConfig().isAuthEnabled()) { + clientConfigBuilder.credentials( + new DefaultCredentials( + sourceConfig.getConnectorConfig().getPassword(), + sourceConfig.getConnectorConfig().getUsername())); + } + if (sourceConfig.getConnectorConfig().isTlsEnable()) { + clientConfigBuilder.trustStore(sourceConfig.getConnectorConfig().getTruststore()).validateHostName(false); + } + ClientConfig clientConfig = clientConfigBuilder.build(); + clientFactory = EventStreamClientFactory.withScope(sourceConfig.getConnectorConfig().getScope(), clientConfig); + readerGroupManager = ReaderGroupManager.withScope(sourceConfig.getConnectorConfig().getScope(), clientConfig); + + initReaders(); + } + + private void initReaders() { + streamManager.listStreams(sourceConfig.getConnectorConfig().getScope()) + .forEachRemaining(stream -> { + if (stream.getStreamName().startsWith("_")) { + return; + } + ReaderGroupConfig readerGroupConfig = + ReaderGroupConfig.builder() + .stream(NameUtils.getScopedStreamName(sourceConfig.getConnectorConfig().getScope(), stream.getStreamName())) + .retentionType(ReaderGroupConfig.StreamDataRetention.AUTOMATIC_RELEASE_AT_LAST_CHECKPOINT) + .build(); + readerGroupManager.createReaderGroup(stream.getStreamName(), readerGroupConfig); + + EventStreamReader reader = clientFactory.createReader( + "PravegaSourceConnector-reader", + stream.getStreamName(), + new ByteArraySerializer(), + ReaderConfig.builder().build()); + this.sourceHandlerMap.put(stream.getStreamName(), new PravegaSourceHandler(reader)); + }); + + } + + @Override + public void start() throws Exception { + sourceHandlerMap.forEach((topic, handler) -> executor.execute(handler)); + started.compareAndSet(false, true); + } + + @Override + public void commit(ConnectRecord record) { + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + sourceHandlerMap.forEach((topic, handler) -> { + readerGroupManager.deleteReaderGroup(topic); + handler.stop(); + }); + sourceHandlerMap.clear(); + readerGroupManager.close(); + clientFactory.close(); + streamManager.close(); + started.compareAndSet(true, false); + } + + @Override + public List poll() { + List connectRecords = new ArrayList<>(DEFAULT_BATCH_SIZE); + for (int count = 0; count < DEFAULT_BATCH_SIZE; ++count) { + try { + CloudEvent event = queue.poll(3, TimeUnit.SECONDS); + if (event == null) { + break; + } + + connectRecords.add(CloudEventUtil.convertEventToRecord(event)); + } catch (InterruptedException e) { + break; + } + } + return connectRecords; + } + + public class PravegaSourceHandler implements Runnable { + + private final EventStreamReader reader; + + private final AtomicBoolean running = new AtomicBoolean(true); + + public PravegaSourceHandler(EventStreamReader reader) { + this.reader = reader; + } + + @Override + public void run() { + while (running.get()) { + try { + EventRead event = reader.readNextEvent(2000); + + byte[] eventByteArray = event.getEvent(); + if (eventByteArray == null) { + continue; + } + PravegaEvent pravegaEvent = PravegaEvent.getFromByteArray(eventByteArray); + CloudEvent cloudEvent = pravegaEvent.convertToCloudEvent(); + queue.add(cloudEvent); + } catch (Exception ex) { + log.error("[PravegaSourceHandler] thread run happen exception.", ex); + } + } + } + + public void stop() { + running.compareAndSet(true, false); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-pravega/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-pravega/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..99bad33863 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: pravegaSink + appId: 5031 + userName: pravegaSinkUser + passWord: pravegaPassWord +connectorConfig: + connectorName: pravegaSink + controllerURI: tcp://127.0.0.1:9090 + scope: eventmesh-pravega + authEnabled: false + username: + password: + tlsEnabled: false + truststore: + clientPoolSize: 8 + queueSize: 512 diff --git a/eventmesh-connectors/eventmesh-connector-pravega/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-pravega/src/main/resources/source-config.yml new file mode 100644 index 0000000000..fe9fb81dcd --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pravega/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: pravegaSource + appId: 5032 + userName: pravegaSourceUser + passWord: pravegaPassWord +connectorConfig: + connectorName: pravegaSource + controllerURI: tcp://127.0.0.1:9090 + scope: eventmesh-pravega + authEnabled: false + username: + password: + tlsEnabled: false + truststore: + clientPoolSize: 8 + queueSize: 512 +offsetStorageConfig: + offsetStorageType: nacos + offsetStorageAddr: 127.0.0.1:8848 + extensions: { + #same with connectorName + dataId: pravegaSource, + #same with group + group: pravegaSource + } diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/build.gradle b/eventmesh-connectors/eventmesh-connector-prometheus/build.gradle new file mode 100644 index 0000000000..d92797a8c4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/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-openconnect:eventmesh-openconnect-java") + implementation 'org.apache.httpcomponents:httpclient' + implementation 'com.github.rholder:guava-retrying' + implementation 'com.alibaba:fastjson' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/gradle.properties b/eventmesh-connectors/eventmesh-connector-prometheus/gradle.properties new file mode 100644 index 0000000000..d3e3811f5f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-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=connector +pluginName=prometheus \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/config/PrometheusServerConfig.java b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/config/PrometheusServerConfig.java new file mode 100644 index 0000000000..3222e28210 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/config/PrometheusServerConfig.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.prometheus.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class PrometheusServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; + +} diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/model/QueryPrometheusReq.java b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/model/QueryPrometheusReq.java new file mode 100644 index 0000000000..cdc1190afc --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/model/QueryPrometheusReq.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.prometheus.model; + +import lombok.Data; + +@Data +public class QueryPrometheusReq { + + private String query; + + private Long start; + + private Long end; + + private String step; +} diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/model/QueryPrometheusRsp.java b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/model/QueryPrometheusRsp.java new file mode 100644 index 0000000000..25a114767a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/model/QueryPrometheusRsp.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.prometheus.model; + +import lombok.Data; + +@Data +public class QueryPrometheusRsp { + + private String status; + + private ResponseData data; + +} diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/model/ResponseData.java b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/model/ResponseData.java new file mode 100644 index 0000000000..73e7a45b78 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/model/ResponseData.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.connector.prometheus.model; + +import java.util.List; + +import lombok.Data; + +@Data +public class ResponseData { + + private String resultType; + + private List result; + +} diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/server/PrometheusConnectServer.java b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/server/PrometheusConnectServer.java new file mode 100644 index 0000000000..88f6c55725 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/server/PrometheusConnectServer.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.prometheus.server; + +import org.apache.eventmesh.connector.prometheus.config.PrometheusServerConfig; +import org.apache.eventmesh.connector.prometheus.source.connector.PrometheusSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PrometheusConnectServer { + + public static void main(String[] args) throws Exception { + + PrometheusServerConfig serverConfig = ConfigUtil.parse(PrometheusServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application prometheusSourceApp = new Application(); + prometheusSourceApp.run(PrometheusSourceConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/source/config/PrometheusSourceConfig.java b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/source/config/PrometheusSourceConfig.java new file mode 100644 index 0000000000..292b7e62f1 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/source/config/PrometheusSourceConfig.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.prometheus.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class PrometheusSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..7e8b7ba93e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/source/config/SourceConnectorConfig.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.connector.prometheus.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private String connectorId; + + private String address; + + private String api; + + private Long initTime; + + private String query; + + private Integer interval; + + private String step; +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/source/connector/PrometheusSourceConnector.java b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/source/connector/PrometheusSourceConnector.java new file mode 100644 index 0000000000..0fe5c87576 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/java/org/apache/eventmesh/connector/prometheus/source/connector/PrometheusSourceConnector.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.connector.prometheus.source.connector; + +import org.apache.eventmesh.connector.prometheus.model.QueryPrometheusReq; +import org.apache.eventmesh.connector.prometheus.model.QueryPrometheusRsp; +import org.apache.eventmesh.connector.prometheus.source.config.PrometheusSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.CloseableHttpResponse; +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.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; + +import java.nio.charset.StandardCharsets; +import java.text.MessageFormat; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.github.rholder.retry.Attempt; +import com.github.rholder.retry.RetryListener; +import com.github.rholder.retry.Retryer; +import com.github.rholder.retry.RetryerBuilder; +import com.github.rholder.retry.StopStrategies; +import com.github.rholder.retry.WaitStrategies; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PrometheusSourceConnector implements Source { + + private static final int MAX_RETRY_TIME = 3; + + private static final int FIXED_WAIT_SECOND = 1; + + private final Retryer retryer = + RetryerBuilder.newBuilder() + .retryIfException() + .retryIfResult(res -> !res) + .withWaitStrategy(WaitStrategies.fixedWait(FIXED_WAIT_SECOND, TimeUnit.SECONDS)) + .withStopStrategy(StopStrategies.stopAfterAttempt(MAX_RETRY_TIME)) + .withRetryListener( + new RetryListener() { + + @Override + public void onRetry(Attempt attempt) { + long times = attempt.getAttemptNumber(); + log.warn("retry invoke http,times={}", times); + } + }) + .build(); + + private PrometheusSourceConfig sourceConfig; + + private CloseableHttpClient httpClient; + + private QueryPrometheusReq queryPrometheusReq; + + private Long initTime; + + private Long startTime; + + private Integer interval; + + private String url; + + @Override + public Class configClass() { + return PrometheusSourceConfig.class; + } + + @Override + public void init(Config config) { + this.sourceConfig = (PrometheusSourceConfig) config; + + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (PrometheusSourceConfig) sourceConnectorContext.getSourceConfig(); + + doInit(); + } + + private void doInit() { + queryPrometheusReq = new QueryPrometheusReq(); + queryPrometheusReq.setQuery(sourceConfig.getConnectorConfig().getQuery()); + queryPrometheusReq.setStep(sourceConfig.getConnectorConfig().getStep()); + + interval = sourceConfig.getConnectorConfig().getInterval(); + initTime = sourceConfig.getConnectorConfig().getInitTime(); + + url = MessageFormat.format("{0}/{1}", sourceConfig.getConnectorConfig().getAddress(), sourceConfig.getConnectorConfig().getApi()); + + // TODO: replace with feature #4481 + httpClient = HttpClientBuilder.create().build(); + } + + @Override + public void start() { + log.info("prometheus source connector start."); + startTime = initTime != null ? initTime : System.currentTimeMillis() / 1000; + } + + @Override + public void commit(ConnectRecord record) { + startTime += interval; + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + log.info("prometheus source connector stop."); + } + + @Override + public List poll() { + try { + if (startTime > System.currentTimeMillis() / 1000 - interval) { + Thread.sleep(interval * 1000); + } + + AtomicReference response = null; + retryer.call(() -> { + try { + queryPrometheusReq.setStart(startTime); + queryPrometheusReq.setEnd(startTime + interval); + + HttpPost httpPost = new HttpPost(url); + httpPost.setEntity(new StringEntity(JSON.toJSONString(queryPrometheusReq), ContentType.APPLICATION_JSON)); + response.set(httpClient.execute(httpPost)); + return response.get().getStatusLine().getStatusCode() == HttpStatus.SC_OK; + } catch (Exception e) { + log.error("invoke http failed", e); + return false; + } + }); + + String result = EntityUtils.toString(response.get().getEntity(), StandardCharsets.UTF_8); + QueryPrometheusRsp responseData = JSONObject.parseObject(result, QueryPrometheusRsp.class); + List connectRecords = + responseData.getData().getResult().stream().map(this::assembleRecord).collect(Collectors.toList()); + + return connectRecords; + } catch (Exception e) { + log.error("failed to poll message from prometheus", e); + return null; + } + } + + private ConnectRecord assembleRecord(String data) { + Long timestamp = System.currentTimeMillis(); + RecordPartition recordPartition = new RecordPartition(); + RecordOffset recordOffset = new RecordOffset(); + + return new ConnectRecord(recordPartition, recordOffset, timestamp, data); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/resources/server-config.yml new file mode 100644 index 0000000000..0cd7b5b5ab --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: false diff --git a/eventmesh-connectors/eventmesh-connector-prometheus/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/resources/source-config.yml new file mode 100644 index 0000000000..5ad5e9bcc9 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-prometheus/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: prometheusSource + appId: 5032 + userName: prometheusSourceUser + passWord: prometheusPassWord +connectorConfig: + connectorName: prometheusSource + connectorId: prometheusSourceId + address: https://127.0.0.1:9090 + api: /api/v1/query_range + initTime: 1237507200 + query: up + interval: 60 + step: 1s \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/build.gradle b/eventmesh-connectors/eventmesh-connector-pulsar/build.gradle new file mode 100644 index 0000000000..4a532ec2b8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/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. + */ + +List pulsar = [ + "org.apache.pulsar:pulsar-client:$pulsar_version" +] +dependencies { + implementation project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation pulsar + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/gradle.properties b/eventmesh-connectors/eventmesh-connector-pulsar/gradle.properties new file mode 100644 index 0000000000..01e274d5fb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/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. +# +pulsar_version=2.11.1 +pluginType=connector +pluginName=pulsar \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/config/PulsarServerConfig.java b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/config/PulsarServerConfig.java new file mode 100644 index 0000000000..56d0b04fed --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/config/PulsarServerConfig.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.pulsar.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; + +@Data +public class PulsarServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/server/PulsarConnectServer.java b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/server/PulsarConnectServer.java new file mode 100644 index 0000000000..c54e085900 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/server/PulsarConnectServer.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.connector.pulsar.server; + +import org.apache.eventmesh.connector.pulsar.config.PulsarServerConfig; +import org.apache.eventmesh.connector.pulsar.sink.connector.PulsarSinkConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PulsarConnectServer { + + public static void main(String[] args) throws Exception { + + PulsarServerConfig serverConfig = ConfigUtil.parse(PulsarServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application rocketmqSourceApp = new Application(); + rocketmqSourceApp.run(PulsarSinkConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application rocketmqSinkApp = new Application(); + rocketmqSinkApp.run(PulsarSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/sink/config/PulsarSinkConfig.java b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/sink/config/PulsarSinkConfig.java new file mode 100644 index 0000000000..8d7bfe384b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/sink/config/PulsarSinkConfig.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.pulsar.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; + +@Data +public class PulsarSinkConfig extends SinkConfig { + + public SinkConnectorConfig connectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..e1ebba09cb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/sink/config/SinkConnectorConfig.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.pulsar.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String serviceUrl; + + private String topic; +} diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/sink/connector/PulsarSinkConnector.java b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/sink/connector/PulsarSinkConnector.java new file mode 100644 index 0000000000..5ea0a0147a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/sink/connector/PulsarSinkConnector.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.connector.pulsar.sink.connector; + +import org.apache.eventmesh.connector.pulsar.sink.config.PulsarSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.pulsar.client.api.MessageId; +import org.apache.pulsar.client.api.Producer; +import org.apache.pulsar.client.api.PulsarClient; +import org.apache.pulsar.client.api.PulsarClientException; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PulsarSinkConnector implements Sink { + + private PulsarSinkConfig sinkConfig; + + private Producer producer; + + @Override + public Class configClass() { + return PulsarSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for pulsar source connector + this.sinkConfig = (PulsarSinkConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + // init config for pulsar source connector + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (PulsarSinkConfig) sinkConnectorContext.getSinkConfig(); + doInit(); + } + + private void doInit() throws Exception { + PulsarClient client = PulsarClient.builder() + .serviceUrl(sinkConfig.getConnectorConfig().getServiceUrl()) + .build(); + producer = client.newProducer() + .topic(sinkConfig.getConnectorConfig().getTopic()) + .create(); + } + + @Override + public void start() throws Exception { + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + try { + producer.close(); + } catch (PulsarClientException e) { + log.error("close pulsar producer failed", e); + } + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + try { + Map props = new HashMap(); + for (String key : connectRecord.getExtensions().keySet()) { + props.put(key, connectRecord.getExtension(key)); + } + MessageId messageId = producer.newMessage() + .value((byte[]) connectRecord.getData()) + .properties(props) + .send(); + } catch (Exception e) { + log.error("put records to pulsar failed", e); + } + } + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/source/config/PulsarSourceConfig.java b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/source/config/PulsarSourceConfig.java new file mode 100644 index 0000000000..a80c2a0e50 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/source/config/PulsarSourceConfig.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.connector.pulsar.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; + +@Data +public class PulsarSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..bb8ff46875 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/source/config/SourceConnectorConfig.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.pulsar.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private String serviceUrl; + + private String topic; +} diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/source/connector/PulsarSourceConnector.java b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/source/connector/PulsarSourceConnector.java new file mode 100644 index 0000000000..718dfc7357 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/java/org/apache/eventmesh/connector/pulsar/source/connector/PulsarSourceConnector.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.connector.pulsar.source.connector; + +import org.apache.eventmesh.connector.pulsar.source.config.PulsarSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import org.apache.pulsar.client.api.Consumer; +import org.apache.pulsar.client.api.Message; +import org.apache.pulsar.client.api.Messages; +import org.apache.pulsar.client.api.PulsarClient; +import org.apache.pulsar.client.api.PulsarClientException; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PulsarSourceConnector implements Source { + + private PulsarSourceConfig sourceConfig; + + private Consumer consumer; + + @Override + public Class configClass() { + return PulsarSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for rocketmq source connector + this.sourceConfig = (PulsarSourceConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (PulsarSourceConfig) sourceConnectorContext.getSourceConfig(); + doInit(); + } + + private void doInit() throws Exception { + PulsarClient client = PulsarClient.builder() + .serviceUrl(sourceConfig.getConnectorConfig().getServiceUrl()) + .build(); + consumer = client.newConsumer() + .topic(sourceConfig.connectorConfig.getTopic()) + .subscriptionName(sourceConfig.getPubSubConfig().getGroup()) + .subscribe(); + } + + @Override + public void start() throws Exception { + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + try { + consumer.close(); + } catch (PulsarClientException e) { + log.error("close pulsar consumer failed", e); + } + } + + @Override + public List poll() { + List connectRecords = new ArrayList<>(); + try { + Messages messages = consumer.batchReceive(); + for (Object msg : messages) { + Long timestamp = System.currentTimeMillis(); + Message message = (Message) msg; + byte[] body = message.getData(); + String bodyStr = new String(body, StandardCharsets.UTF_8); + Map map = new HashMap<>(); + map.put("topic", consumer.getTopic()); + map.put("queueId", String.valueOf(message.getSequenceId())); + RecordPartition partition = new RecordPartition(map); + ConnectRecord connectRecord = new ConnectRecord(partition, null, timestamp, bodyStr); + connectRecord.addExtension("topic", consumer.getTopic()); + connectRecords.add(connectRecord); + } + consumer.acknowledge(messages); + } catch (PulsarClientException e) { + log.error("consumer msg from pulsar failed", e); + } + return connectRecords; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..e716e496da --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: pulsarSink + appId: 5031 + userName: pulsarSinkUser + passWord: pulsarPassWord +sinkConnectorConfig: + connectorName: pulsarSink + serviceUrl: 127.0.0.1:6650 + topic: TopicTest diff --git a/eventmesh-connectors/eventmesh-connector-pulsar/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/resources/source-config.yml new file mode 100644 index 0000000000..c4bd62595d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-pulsar/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: pulsarSource + appId: 5032 + userName: rocketmqSourceUser + passWord: rocketmqPassWord +sourceConnectorConfig: + connectorName: pulsarSource + serviceUrl: 127.0.0.1:6650 + topic: TopicTest diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/build.gradle b/eventmesh-connectors/eventmesh-connector-rabbitmq/build.gradle new file mode 100644 index 0000000000..b4edbe1f8a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/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. + */ + + +configurations { + implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' + implementation.exclude group: 'log4j', module: 'log4j' +} + +dependencies { + api project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation project(":eventmesh-common") + // rabbitmq + implementation 'com.rabbitmq:amqp-client:5.16.0' + + implementation 'io.cloudevents:cloudevents-json-jackson' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/gradle.properties b/eventmesh-connectors/eventmesh-connector-rabbitmq/gradle.properties new file mode 100644 index 0000000000..b9fedf465a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/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=rabbitmq \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/client/RabbitmqClient.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/client/RabbitmqClient.java new file mode 100644 index 0000000000..34cda9620e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/client/RabbitmqClient.java @@ -0,0 +1,146 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.connector.rabbitmq.client; + +import org.apache.commons.lang3.StringUtils; + +import com.rabbitmq.client.BuiltinExchangeType; +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RabbitmqClient { + + private final RabbitmqConnectionFactory rabbitmqConnectionFactory; + + public RabbitmqClient(RabbitmqConnectionFactory rabbitmqConnectionFactory) { + this.rabbitmqConnectionFactory = rabbitmqConnectionFactory; + } + + /** + * get rabbitmq connection + * + * @param host host + * @param username username + * @param passwd password + * @param port port + * @param virtualHost virtual host + * @return connection + * @throws Exception Exception + */ + public Connection getConnection(String host, String username, + String passwd, int port, + String virtualHost) throws Exception { + ConnectionFactory factory = rabbitmqConnectionFactory.createConnectionFactory(); + factory.setHost(host.trim()); + factory.setPort(port); + if (StringUtils.isNotEmpty(virtualHost)) { + factory.setVirtualHost(virtualHost.trim()); + } + factory.setUsername(username); + factory.setPassword(passwd.trim()); + + return rabbitmqConnectionFactory.createConnection(factory); + } + + /** + * send message + * + * @param channel channel + * @param exchangeName exchange name + * @param routingKey routing key + * @param message message + * @throws Exception Exception + */ + public void publish(Channel channel, String exchangeName, + String routingKey, byte[] message) throws Exception { + channel.basicPublish(exchangeName, routingKey, null, message); + } + + /** + * binding queue + * + * @param channel channel + * @param builtinExchangeType exchange type + * @param exchangeName exchange name + * @param routingKey routing key + * @param queueName queue name + */ + public void binding(Channel channel, BuiltinExchangeType builtinExchangeType, + String exchangeName, String routingKey, String queueName) { + try { + channel.exchangeDeclare(exchangeName, builtinExchangeType.getType(), true, + false, false, null); + channel.queueDeclare(queueName, false, false, + false, null); + routingKey = builtinExchangeType.getType().equals(BuiltinExchangeType.FANOUT.getType()) ? "" : routingKey; + channel.queueBind(queueName, exchangeName, routingKey); + } catch (Exception ex) { + log.error("[RabbitmqClient] binding happen exception.", ex); + } + } + + /** + * unbinding queue + * + * @param channel channel + * @param exchangeName exchange name + * @param routingKey routing key + * @param queueName queue name + */ + public void unbinding(Channel channel, String exchangeName, String routingKey, String queueName) { + try { + channel.queueUnbind(queueName, exchangeName, routingKey); + } catch (Exception ex) { + log.error("[RabbitmqClient] unbinding happen exception.", ex); + } + } + + /** + * close connection + * + * @param connection connection + */ + public void closeConnection(Connection connection) { + if (null != connection) { + try { + connection.close(); + } catch (Exception ex) { + log.error("[RabbitmqClient] connection close happen exception.", ex); + } + } + } + + /** + * close channel + * + * @param channel channel + */ + public void closeChannel(Channel channel) { + if (null != channel) { + try { + channel.close(); + } catch (Exception ex) { + log.error("[RabbitmqClient] channel close happen exception.", ex); + } + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/client/RabbitmqConnectionFactory.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/client/RabbitmqConnectionFactory.java new file mode 100644 index 0000000000..82f6b929e3 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/client/RabbitmqConnectionFactory.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.connector.rabbitmq.client; + +import java.io.IOException; +import java.util.concurrent.TimeoutException; + +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; + +public class RabbitmqConnectionFactory { + + public ConnectionFactory createConnectionFactory() { + return new ConnectionFactory(); + } + + public Connection createConnection(ConnectionFactory connectionFactory) throws IOException, TimeoutException { + return connectionFactory.newConnection(); + } + + public Channel createChannel(Connection connection) throws IOException { + return connection.createChannel(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/cloudevent/RabbitmqCloudEvent.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/cloudevent/RabbitmqCloudEvent.java new file mode 100644 index 0000000000..06eced2ae5 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/cloudevent/RabbitmqCloudEvent.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.connector.rabbitmq.cloudevent; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.connector.rabbitmq.exception.RabbitmqConnectorException; +import org.apache.eventmesh.connector.rabbitmq.utils.ByteArrayUtils; + +import java.io.Serializable; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; +import io.cloudevents.core.builder.CloudEventBuilder; + +import com.fasterxml.jackson.core.type.TypeReference; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class RabbitmqCloudEvent implements Serializable { + + private SpecVersion version; + private String data; + private Map extensions = new HashMap<>(); + + public CloudEvent convertToCloudEvent() throws Exception { + CloudEventBuilder builder; + switch (version) { + case V03: + builder = CloudEventBuilder.v03(); + break; + case V1: + builder = CloudEventBuilder.v1(); + break; + default: + throw new RabbitmqConnectorException(String.format("CloudEvent version %s does not support.", version)); + } + builder.withData(data.getBytes(StandardCharsets.UTF_8)) + .withId(extensions.remove("id")) + .withSource(URI.create(extensions.remove("source"))) + .withType(extensions.remove("type")) + .withDataContentType(extensions.remove("datacontenttype")) + .withSubject(extensions.remove("subject")); + extensions.forEach(builder::withExtension); + + return builder.build(); + } + + public static byte[] toByteArray(RabbitmqCloudEvent rabbitmqCloudEvent) throws Exception { + Optional optionalBytes = ByteArrayUtils.objectToBytes(rabbitmqCloudEvent); + return optionalBytes.orElseGet(() -> new byte[]{}); + } + + public static RabbitmqCloudEvent getFromByteArray(byte[] body) { + return JsonUtils.parseTypeReferenceObject(new String(body, Constants.DEFAULT_CHARSET), new TypeReference() { + }); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/cloudevent/RabbitmqCloudEventWriter.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/cloudevent/RabbitmqCloudEventWriter.java new file mode 100644 index 0000000000..a82cbc9e3c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/cloudevent/RabbitmqCloudEventWriter.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.rabbitmq.cloudevent; + +import java.nio.charset.StandardCharsets; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +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 class RabbitmqCloudEventWriter + implements MessageWriter, RabbitmqCloudEvent>, CloudEventWriter { + + private final RabbitmqCloudEvent rabbitmqCloudEvent; + + public RabbitmqCloudEventWriter() { + rabbitmqCloudEvent = new RabbitmqCloudEvent(); + } + + @Override + public RabbitmqCloudEvent setEvent(@Nullable EventFormat format, @Nonnull byte[] value) throws CloudEventRWException { + rabbitmqCloudEvent.setData(new String(value, StandardCharsets.UTF_8)); + return rabbitmqCloudEvent; + } + + @Override + public RabbitmqCloudEvent end(CloudEventData data) throws CloudEventRWException { + rabbitmqCloudEvent.setData(new String(data.toBytes(), StandardCharsets.UTF_8)); + return rabbitmqCloudEvent; + } + + @Override + public RabbitmqCloudEvent end() throws CloudEventRWException { + rabbitmqCloudEvent.setData(""); + return rabbitmqCloudEvent; + } + + @Override + public CloudEventContextWriter withContextAttribute(@Nonnull String name, @Nonnull String value) throws CloudEventRWException { + rabbitmqCloudEvent.getExtensions().put(name, value); + return this; + } + + @Override + public CloudEventWriter create(SpecVersion version) throws CloudEventRWException { + rabbitmqCloudEvent.setVersion(version); + return this; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/config/RabbitMQServerConfig.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/config/RabbitMQServerConfig.java new file mode 100644 index 0000000000..9b33ce0c83 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/config/RabbitMQServerConfig.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.connector.rabbitmq.config; + +import lombok.Data; + +@Data +public class RabbitMQServerConfig { + + private boolean sourceEnable; + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/exception/RabbitmqConnectorException.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/exception/RabbitmqConnectorException.java new file mode 100644 index 0000000000..c107277a2c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/exception/RabbitmqConnectorException.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.rabbitmq.exception; + +public class RabbitmqConnectorException extends Exception { + + public RabbitmqConnectorException(String message) { + super(message); + } + + public RabbitmqConnectorException(Throwable throwable) { + super(throwable); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/server/RabbitMQConnectorServer.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/server/RabbitMQConnectorServer.java new file mode 100644 index 0000000000..529392c327 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/server/RabbitMQConnectorServer.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.connector.rabbitmq.server; + +import org.apache.eventmesh.connector.rabbitmq.config.RabbitMQServerConfig; +import org.apache.eventmesh.connector.rabbitmq.sink.connector.RabbitMQSinkConnector; +import org.apache.eventmesh.connector.rabbitmq.source.connector.RabbitMQSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RabbitMQConnectorServer { + + public static void main(String[] args) throws Exception { + + RabbitMQServerConfig serverConfig = ConfigUtil.parse(RabbitMQServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application rabbitmqSourceApp = new Application(); + rabbitmqSourceApp.run(RabbitMQSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application rabbitmqSinkApp = new Application(); + rabbitmqSinkApp.run(RabbitMQSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/sink/config/RabbitMQSinkConfig.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/sink/config/RabbitMQSinkConfig.java new file mode 100644 index 0000000000..1c4ec66d47 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/sink/config/RabbitMQSinkConfig.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.connector.rabbitmq.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class RabbitMQSinkConfig extends SinkConfig { + + public SinkConnectorConfig connectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..358964bdc0 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/sink/config/SinkConnectorConfig.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.connector.rabbitmq.sink.config; + +import com.rabbitmq.client.BuiltinExchangeType; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String host; + + private int port; + + private String username; + + private String passwd; + + private String virtualHost; + + private BuiltinExchangeType exchangeType; + + private String exchangeName; + + private String routingKey; + + private String queueName; + + private boolean autoAck; +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/sink/connector/RabbitMQSinkConnector.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/sink/connector/RabbitMQSinkConnector.java new file mode 100644 index 0000000000..250f31c5bb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/sink/connector/RabbitMQSinkConnector.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.connector.rabbitmq.sink.connector; + +import org.apache.eventmesh.connector.rabbitmq.client.RabbitmqClient; +import org.apache.eventmesh.connector.rabbitmq.client.RabbitmqConnectionFactory; +import org.apache.eventmesh.connector.rabbitmq.cloudevent.RabbitmqCloudEvent; +import org.apache.eventmesh.connector.rabbitmq.cloudevent.RabbitmqCloudEventWriter; +import org.apache.eventmesh.connector.rabbitmq.sink.config.RabbitMQSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.List; + +import io.cloudevents.CloudEvent; + +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RabbitMQSinkConnector implements Sink { + + private RabbitMQSinkConfig sinkConfig; + + private final RabbitmqConnectionFactory rabbitmqConnectionFactory = new RabbitmqConnectionFactory(); + + private RabbitmqClient rabbitmqClient; + + private Connection connection; + + private Channel channel; + + private volatile boolean started = false; + + @Override + public Class configClass() { + return RabbitMQSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + this.sinkConfig = (RabbitMQSinkConfig) ((SinkConnectorContext) connectorContext).getSinkConfig(); + this.rabbitmqClient = new RabbitmqClient(rabbitmqConnectionFactory); + this.connection = rabbitmqClient.getConnection(sinkConfig.getConnectorConfig().getHost(), + sinkConfig.getConnectorConfig().getUsername(), + sinkConfig.getConnectorConfig().getPasswd(), + sinkConfig.getConnectorConfig().getPort(), + sinkConfig.getConnectorConfig().getVirtualHost()); + this.channel = rabbitmqConnectionFactory.createChannel(connection); + } + + @Override + public void start() throws Exception { + if (!started) { + rabbitmqClient.binding(channel, sinkConfig.getConnectorConfig().getExchangeType(), sinkConfig.getConnectorConfig().getExchangeName(), + sinkConfig.getConnectorConfig().getRoutingKey(), sinkConfig.getConnectorConfig().getQueueName()); + started = true; + } + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + if (started) { + try { + rabbitmqClient.closeConnection(connection); + rabbitmqClient.closeChannel(channel); + } finally { + started = false; + } + } + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + CloudEvent event = CloudEventUtil.convertRecordToEvent(connectRecord); + try { + RabbitmqCloudEventWriter writer = new RabbitmqCloudEventWriter(); + RabbitmqCloudEvent rabbitmqCloudEvent = writer.writeBinary(event); + byte[] data = RabbitmqCloudEvent.toByteArray(rabbitmqCloudEvent); + rabbitmqClient.publish(channel, sinkConfig.getConnectorConfig().getExchangeName(), + sinkConfig.getConnectorConfig().getRoutingKey(), data); + } catch (InterruptedException e) { + Thread currentThread = Thread.currentThread(); + log.warn("[RabbitMQSinkConnector] Interrupting thread {} due to exception {}", + currentThread.getName(), e.getMessage()); + currentThread.interrupt(); + } catch (Exception e) { + log.error("[RabbitMQSinkConnector] sendResult has error : ", e); + } + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/source/config/RabbitMQSourceConfig.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/source/config/RabbitMQSourceConfig.java new file mode 100644 index 0000000000..55ce402ae7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/source/config/RabbitMQSourceConfig.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.rabbitmq.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class RabbitMQSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..d83149f9ca --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/source/config/SourceConnectorConfig.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.connector.rabbitmq.source.config; + +import com.rabbitmq.client.BuiltinExchangeType; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private String host; + + private int port; + + private String username; + + private String passwd; + + private String virtualHost; + + private BuiltinExchangeType exchangeType; + + private String exchangeName; + + private String routingKey; + + private String queueName; + + private boolean autoAck; +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/source/connector/RabbitMQSourceConnector.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/source/connector/RabbitMQSourceConnector.java new file mode 100644 index 0000000000..95b09034ef --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/source/connector/RabbitMQSourceConnector.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.connector.rabbitmq.source.connector; + +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.connector.rabbitmq.client.RabbitmqClient; +import org.apache.eventmesh.connector.rabbitmq.client.RabbitmqConnectionFactory; +import org.apache.eventmesh.connector.rabbitmq.cloudevent.RabbitmqCloudEvent; +import org.apache.eventmesh.connector.rabbitmq.source.config.RabbitMQSourceConfig; +import org.apache.eventmesh.connector.rabbitmq.source.config.SourceConnectorConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.cloudevents.CloudEvent; + +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.GetResponse; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RabbitMQSourceConnector implements Source { + + private RabbitMQSourceConfig sourceConfig; + + private volatile boolean started = false; + + private static final int DEFAULT_BATCH_SIZE = 10; + + private BlockingQueue queue; + + private final RabbitmqConnectionFactory rabbitmqConnectionFactory = new RabbitmqConnectionFactory(); + + private RabbitMQSourceHandler rabbitMQSourceHandler; + + private RabbitmqClient rabbitmqClient; + + private Connection connection; + + private Channel channel; + + private final ThreadPoolExecutor executor = ThreadPoolFactory.createThreadPoolExecutor( + Runtime.getRuntime().availableProcessors() * 2, + Runtime.getRuntime().availableProcessors() * 2, + "EventMesh-RabbitMQSourceConnector-"); + + @Override + public Class configClass() { + return RabbitMQSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + this.queue = new LinkedBlockingQueue<>(1000); + this.sourceConfig = (RabbitMQSourceConfig) ((SourceConnectorContext) connectorContext).getSourceConfig(); + this.rabbitmqClient = new RabbitmqClient(rabbitmqConnectionFactory); + this.connection = rabbitmqClient.getConnection(sourceConfig.getConnectorConfig().getHost(), + sourceConfig.getConnectorConfig().getUsername(), + sourceConfig.getConnectorConfig().getPasswd(), + sourceConfig.getConnectorConfig().getPort(), + sourceConfig.getConnectorConfig().getVirtualHost()); + this.channel = rabbitmqConnectionFactory.createChannel(connection); + this.rabbitMQSourceHandler = new RabbitMQSourceHandler(channel, sourceConfig.getConnectorConfig()); + } + + @Override + public void start() throws Exception { + if (!started) { + rabbitmqClient.binding(channel, sourceConfig.getConnectorConfig().getExchangeType(), sourceConfig.getConnectorConfig().getExchangeName(), + sourceConfig.getConnectorConfig().getRoutingKey(), sourceConfig.getConnectorConfig().getQueueName()); + executor.execute(this.rabbitMQSourceHandler); + started = true; + } + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + if (started) { + try { + rabbitmqClient.unbinding(channel, sourceConfig.getConnectorConfig().getExchangeName(), + sourceConfig.getConnectorConfig().getRoutingKey(), sourceConfig.getConnectorConfig().getQueueName()); + rabbitmqClient.closeConnection(connection); + rabbitmqClient.closeChannel(channel); + rabbitMQSourceHandler.stop(); + } finally { + started = false; + } + } + } + + @Override + public List poll() { + List connectRecords = new ArrayList<>(DEFAULT_BATCH_SIZE); + for (int count = 0; count < DEFAULT_BATCH_SIZE; ++count) { + try { + CloudEvent event = queue.poll(3, TimeUnit.SECONDS); + if (event == null) { + break; + } + + connectRecords.add(CloudEventUtil.convertEventToRecord(event)); + } catch (InterruptedException e) { + break; + } + } + return connectRecords; + } + + public class RabbitMQSourceHandler implements Runnable { + + private final Channel channel; + private final SourceConnectorConfig connectorConfig; + private final AtomicBoolean stop = new AtomicBoolean(false); + + public RabbitMQSourceHandler(Channel channel, SourceConnectorConfig connectorConfig) { + this.channel = channel; + this.connectorConfig = connectorConfig; + } + + @Override + public void run() { + while (!stop.get()) { + try { + GetResponse response = channel.basicGet(connectorConfig.getQueueName(), connectorConfig.isAutoAck()); + if (response != null) { + RabbitmqCloudEvent rabbitmqCloudEvent = RabbitmqCloudEvent.getFromByteArray(response.getBody()); + CloudEvent event = rabbitmqCloudEvent.convertToCloudEvent(); + if (event != null) { + queue.add(event); + } + if (!connectorConfig.isAutoAck()) { + channel.basicAck(response.getEnvelope().getDeliveryTag(), false); + } + } + } catch (Exception ex) { + log.error("[RabbitMQSourceHandler] thread run happen exception.", ex); + } + } + } + + public void stop() { + stop.compareAndSet(false, true); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/utils/ByteArrayUtils.java b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/utils/ByteArrayUtils.java new file mode 100644 index 0000000000..57f9423258 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/java/org/apache/eventmesh/connector/rabbitmq/utils/ByteArrayUtils.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.connector.rabbitmq.utils; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.utils.JsonUtils; + +import java.io.IOException; +import java.util.Optional; + +import com.fasterxml.jackson.core.type.TypeReference; + +@SuppressWarnings("all") +public class ByteArrayUtils { + + public static Optional objectToBytes(T obj) throws IOException { + String s = JsonUtils.toJSONString(obj); + byte[] bytes = s.getBytes(Constants.DEFAULT_CHARSET); + return Optional.ofNullable(bytes); + } + + public static Optional bytesToObject(byte[] bytes) throws IOException, ClassNotFoundException { + T t = JsonUtils.parseTypeReferenceObject(new String(bytes, Constants.DEFAULT_CHARSET), new TypeReference() { + }); + return Optional.ofNullable(t); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..f4eea14c79 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/resources/sink-config.yml @@ -0,0 +1,38 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: rabbitmqSink + appId: 5031 + userName: rabbitmqSinkUser + passWord: rabbitmqPassWord +connectorConfig: + connectorName: rabbitmqSink + host: + port: + username: + passwd: + virtualHost: + exchangeType: TOPIC + exchangeName: + routingKey: + queueName: + autoAck: true diff --git a/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/resources/source-config.yml new file mode 100644 index 0000000000..bc0fdfeda5 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rabbitmq/src/main/resources/source-config.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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: rabbitmqSource + appId: 5032 + userName: rabbitmqSourceUser + passWord: rabbitmqPassWord +connectorConfig: + connectorName: rabbitmqSource + host: + port: + username: + passwd: + virtualHost: + exchangeType: TOPIC + exchangeName: + routingKey: + queueName: + autoAck: true +offsetStorageConfig: + offsetStorageType: nacos + offsetStorageAddr: 127.0.0.1:8848 + extensions: { + #same with connectorName + dataId: rabbitmqSource, + #same with group + group: rabbitmqSource + } diff --git a/eventmesh-connectors/eventmesh-connector-redis/build.gradle b/eventmesh-connectors/eventmesh-connector-redis/build.gradle new file mode 100644 index 0000000000..425a10570a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/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 { + implementation project(":eventmesh-openconnect:eventmesh-openconnect-java") + + implementation 'org.redisson:redisson:3.17.3' + + api 'io.cloudevents:cloudevents-json-jackson' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation 'ai.grakn:redis-mock:0.1.6' + testImplementation project(":eventmesh-common") +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-redis/gradle.properties b/eventmesh-connectors/eventmesh-connector-redis/gradle.properties new file mode 100644 index 0000000000..88d5964c29 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/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=redis \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/cloudevent/CloudEventCodec.java b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/cloudevent/CloudEventCodec.java new file mode 100644 index 0000000000..8fb347354d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/cloudevent/CloudEventCodec.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.redis.cloudevent; + +import org.redisson.client.codec.BaseCodec; +import org.redisson.client.protocol.Decoder; +import org.redisson.client.protocol.Encoder; + +import io.cloudevents.CloudEvent; +import io.cloudevents.jackson.JsonFormat; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; + +/** + * TODO: Duplicate with org.apache.eventmesh.storage.redis.cloudevent.CloudEventCodec + */ +public class CloudEventCodec extends BaseCodec { + + private static final CloudEventCodec INSTANCE = new CloudEventCodec(); + + private static final JsonFormat jsonFormat = new JsonFormat(false, true); + + private CloudEventCodec() { + // To prevent class instantiation + } + + public static CloudEventCodec getInstance() { + return INSTANCE; + } + + private static final Encoder encoder = in -> { + ByteBuf out = ByteBufAllocator.DEFAULT.buffer(); + if (in instanceof CloudEvent) { + out.writeBytes(jsonFormat.serialize((CloudEvent) in)); + return out; + } + throw new IllegalStateException("Illegal object type: " + in.getClass().getSimpleName()); + }; + + private static final Decoder decoder = (buf, state) -> { + final byte[] bytes = new byte[buf.readableBytes()]; + buf.getBytes(buf.readerIndex(), bytes); + return jsonFormat.deserialize(bytes); + }; + + @Override + public Decoder getValueDecoder() { + return decoder; + } + + @Override + public Encoder getValueEncoder() { + return encoder; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/config/RedisServerConfig.java b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/config/RedisServerConfig.java new file mode 100644 index 0000000000..6b55b0e6e9 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/config/RedisServerConfig.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.connector.redis.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; + +@Data +public class RedisServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; + +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/server/RedisConnectServer.java b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/server/RedisConnectServer.java new file mode 100644 index 0000000000..c9abdb5ee7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/server/RedisConnectServer.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.connector.redis.server; + +import org.apache.eventmesh.connector.redis.config.RedisServerConfig; +import org.apache.eventmesh.connector.redis.sink.connector.RedisSinkConnector; +import org.apache.eventmesh.connector.redis.source.connector.RedisSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RedisConnectServer { + + public static void main(String[] args) throws Exception { + + RedisServerConfig serverConfig = ConfigUtil.parse(RedisServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application redisSourceApp = new Application(); + redisSourceApp.run(RedisSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application redisSinkApp = new Application(); + redisSinkApp.run(RedisSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/sink/config/RedisSinkConfig.java b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/sink/config/RedisSinkConfig.java new file mode 100644 index 0000000000..62cddbf312 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/sink/config/RedisSinkConfig.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.redis.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; + +@Data +public class RedisSinkConfig extends SinkConfig { + + public SinkConnectorConfig connectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..34fb0326a4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/sink/config/SinkConnectorConfig.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.redis.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String server; + + private String topic; +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/sink/connector/RedisSinkConnector.java b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/sink/connector/RedisSinkConnector.java new file mode 100644 index 0000000000..e07e05e276 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/sink/connector/RedisSinkConnector.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.redis.sink.connector; + +import org.apache.eventmesh.connector.redis.cloudevent.CloudEventCodec; +import org.apache.eventmesh.connector.redis.sink.config.RedisSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.List; + +import org.redisson.Redisson; +import org.redisson.api.RTopic; +import org.redisson.api.RedissonClient; + +import io.cloudevents.CloudEvent; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RedisSinkConnector implements Sink { + + private RTopic topic; + + private RedisSinkConfig sinkConfig; + + private RedissonClient redissonClient; + + @Override + public Class configClass() { + return RedisSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + this.sinkConfig = (RedisSinkConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (RedisSinkConfig) sinkConnectorContext.getSinkConfig(); + doInit(); + } + + private void doInit() { + org.redisson.config.Config redisConfig = new org.redisson.config.Config(); + redisConfig.useSingleServer().setAddress(sinkConfig.connectorConfig.getServer()); + redisConfig.setCodec(CloudEventCodec.getInstance()); + this.redissonClient = Redisson.create(redisConfig); + } + + @Override + public void start() throws Exception { + this.topic = redissonClient.getTopic(sinkConfig.connectorConfig.getTopic()); + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() throws Exception { + this.redissonClient.shutdown(); + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + CloudEvent event = CloudEventUtil.convertRecordToEvent(connectRecord); + try { + long publish = topic.publish(event); + } catch (Exception e) { + log.error("[RedisSinkConnector] sendResult has error : ", e); + } + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/source/config/RedisSourceConfig.java b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/source/config/RedisSourceConfig.java new file mode 100644 index 0000000000..f01a556c9f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/source/config/RedisSourceConfig.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.redis.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; + +@Data +public class RedisSourceConfig extends SourceConfig { + + public SourceConnectorConfig connectorConfig; + +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..9913e16320 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/source/config/SourceConnectorConfig.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.connector.redis.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private String server; + + private String topic; + +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/source/connector/RedisSourceConnector.java b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/source/connector/RedisSourceConnector.java new file mode 100644 index 0000000000..2933d545dd --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/java/org/apache/eventmesh/connector/redis/source/connector/RedisSourceConnector.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.connector.redis.source.connector; + +import org.apache.eventmesh.connector.redis.cloudevent.CloudEventCodec; +import org.apache.eventmesh.connector.redis.source.config.RedisSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.redisson.Redisson; +import org.redisson.api.RTopic; +import org.redisson.api.RedissonClient; + +import io.cloudevents.CloudEvent; + +public class RedisSourceConnector implements Source { + + private static final int DEFAULT_BATCH_SIZE = 10; + + private RTopic topic; + + private RedisSourceConfig sourceConfig; + + private RedissonClient redissonClient; + + private BlockingQueue queue; + + @Override + public Class configClass() { + return RedisSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + this.sourceConfig = (RedisSourceConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (RedisSourceConfig) sourceConnectorContext.getSourceConfig(); + doInit(); + } + + private void doInit() { + org.redisson.config.Config redisConfig = new org.redisson.config.Config(); + redisConfig.useSingleServer().setAddress(sourceConfig.connectorConfig.getServer()); + redisConfig.setCodec(CloudEventCodec.getInstance()); + this.redissonClient = Redisson.create(redisConfig); + this.queue = new LinkedBlockingQueue<>(1000); + } + + @Override + public void start() throws Exception { + this.topic = redissonClient.getTopic(sourceConfig.connectorConfig.getTopic()); + this.topic.addListener(CloudEvent.class, (channel, msg) -> { + queue.add(msg); + }); + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() throws Exception { + this.topic.removeAllListeners(); + this.redissonClient.shutdown(); + } + + @Override + public List poll() { + List connectRecords = new ArrayList<>(DEFAULT_BATCH_SIZE); + for (int count = 0; count < DEFAULT_BATCH_SIZE; ++count) { + try { + CloudEvent event = queue.poll(3, TimeUnit.SECONDS); + if (event == null) { + break; + } + + connectRecords.add(CloudEventUtil.convertEventToRecord(event)); + } catch (InterruptedException e) { + break; + } + } + return connectRecords; + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-redis/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-redis/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..596006a2a1 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: redisSink + appId: 5031 + userName: redisSinkUser + passWord: redisPassWord +connectorConfig: + connectorName: redisSink + server: redis://127.0.0.1:6379 + topic: SinkTopic + diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-redis/src/main/resources/source-config.yml new file mode 100644 index 0000000000..5d31ad0fcb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: redisSource + appId: 5032 + userName: redisSourceUser + passWord: redisPassWord +connectorConfig: + connectorName: redisSource + server: redis://127.0.0.1:6379 + topic: SourceTopic diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/test/java/org/apache/eventmesh/connector/redis/AbstractRedisServer.java b/eventmesh-connectors/eventmesh-connector-redis/src/test/java/org/apache/eventmesh/connector/redis/AbstractRedisServer.java new file mode 100644 index 0000000000..46272496f4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/test/java/org/apache/eventmesh/connector/redis/AbstractRedisServer.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.connector.redis; + +import ai.grakn.redismock.RedisServer; + +public abstract class AbstractRedisServer { + + protected RedisServer redisServer; + + public void setupRedisServer(int port) throws Exception { + redisServer = RedisServer.newRedisServer(port); + redisServer.start(); + } + + public void shutdownRedisServer() { + if (redisServer != null) { + redisServer.stop(); + } + } + + public static int getPortFromUrl(String url) { + return Integer.parseInt(url.substring(url.lastIndexOf(":") + 1)); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/test/java/org/apache/eventmesh/connector/redis/sink/connector/RedisSinkConnectorTest.java b/eventmesh-connectors/eventmesh-connector-redis/src/test/java/org/apache/eventmesh/connector/redis/sink/connector/RedisSinkConnectorTest.java new file mode 100644 index 0000000000..13ec4f7379 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/test/java/org/apache/eventmesh/connector/redis/sink/connector/RedisSinkConnectorTest.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.connector.redis.sink.connector; + +import org.apache.eventmesh.connector.redis.AbstractRedisServer; +import org.apache.eventmesh.connector.redis.cloudevent.CloudEventCodec; +import org.apache.eventmesh.connector.redis.sink.config.RedisSinkConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.redisson.Redisson; +import org.redisson.api.RTopic; +import org.redisson.config.Config; + +import io.cloudevents.CloudEvent; + +public class RedisSinkConnectorTest extends AbstractRedisServer { + + private RedisSinkConnector connector; + + private Redisson redisson; + + private RedisSinkConfig sinkConfig; + + @BeforeEach + public void setUp() throws Exception { + connector = new RedisSinkConnector(); + sinkConfig = (RedisSinkConfig) ConfigUtil.parse(connector.configClass()); + setupRedisServer(getPortFromUrl(sinkConfig.getConnectorConfig().getServer())); + connector.init(sinkConfig); + connector.start(); + Config config = new Config(); + config.setCodec(CloudEventCodec.getInstance()); + config.useSingleServer() + .setAddress(sinkConfig.getConnectorConfig().getServer()); + redisson = (Redisson) Redisson.create(config); + } + + @Test + public void testPutConnectRecords() throws InterruptedException { + RTopic topic = redisson.getTopic(sinkConfig.connectorConfig.getTopic()); + + final String expectedMessage = "\"testRedisMessage\""; + final int expectedCount = 5; + final CountDownLatch downLatch = new CountDownLatch(expectedCount); + topic.addListener(CloudEvent.class, (channel, msg) -> { + downLatch.countDown(); + Assertions.assertNotNull(msg.getData()); + Assertions.assertEquals(expectedMessage, new String(msg.getData().toBytes())); + }); + + List records = new ArrayList<>(); + for (int i = 0; i < expectedCount; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, System.currentTimeMillis(), + expectedMessage.getBytes(StandardCharsets.UTF_8)); + connectRecord.addExtension("id", String.valueOf(UUID.randomUUID())); + connectRecord.addExtension("source", "testSource"); + connectRecord.addExtension("type", "testType"); + records.add(connectRecord); + } + connector.put(records); + Assertions.assertTrue(downLatch.await(10, TimeUnit.SECONDS)); + } + + @AfterEach + public void tearDown() throws Exception { + connector.stop(); + redisson.shutdown(); + shutdownRedisServer(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/test/java/org/apache/eventmesh/connector/redis/source/connector/RedisSourceConnectorTest.java b/eventmesh-connectors/eventmesh-connector-redis/src/test/java/org/apache/eventmesh/connector/redis/source/connector/RedisSourceConnectorTest.java new file mode 100644 index 0000000000..da68a5b170 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/test/java/org/apache/eventmesh/connector/redis/source/connector/RedisSourceConnectorTest.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.connector.redis.source.connector; + +import org.apache.eventmesh.connector.redis.AbstractRedisServer; +import org.apache.eventmesh.connector.redis.cloudevent.CloudEventCodec; +import org.apache.eventmesh.connector.redis.source.config.RedisSourceConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.redisson.Redisson; +import org.redisson.api.RTopic; +import org.redisson.config.Config; + +public class RedisSourceConnectorTest extends AbstractRedisServer { + + private RedisSourceConnector connector; + + private final String expectedMessage = "testRedisMessage"; + + private RTopic topic; + + private Redisson redisson; + + @BeforeEach + public void setUp() throws Exception { + connector = new RedisSourceConnector(); + RedisSourceConfig sourceConfig = (RedisSourceConfig) ConfigUtil.parse(connector.configClass()); + setupRedisServer(getPortFromUrl(sourceConfig.getConnectorConfig().getServer())); + connector.init(sourceConfig); + connector.start(); + Config config = new Config(); + config.setCodec(CloudEventCodec.getInstance()); + config.useSingleServer() + .setAddress(sourceConfig.getConnectorConfig().getServer()); + redisson = (Redisson) Redisson.create(config); + topic = redisson.getTopic(sourceConfig.connectorConfig.getTopic()); + } + + @Test + public void testPollConnectRecords() throws Exception { + publishMockEvents(); + List connectRecords = connector.poll(); + for (ConnectRecord connectRecord : connectRecords) { + String actualMessage = new String((byte[]) connectRecord.getData()); + Assertions.assertEquals(expectedMessage, actualMessage); + } + } + + private void publishMockEvents() { + int mockCount = 5; + for (int i = 0; i < mockCount; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, System.currentTimeMillis(), + ("\"" + expectedMessage + "\"").getBytes(StandardCharsets.UTF_8)); + connectRecord.addExtension("id", String.valueOf(UUID.randomUUID())); + connectRecord.addExtension("source", "testSource"); + connectRecord.addExtension("topic", "testTopic"); + connectRecord.addExtension("type", "testType"); + connectRecord.addExtension("datacontenttype", "testdatacontenttype"); + topic.publish(CloudEventUtil.convertRecordToEvent(connectRecord)); + } + } + + @AfterEach + public void tearDown() throws Exception { + connector.stop(); + redisson.shutdown(); + shutdownRedisServer(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/test/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-redis/src/test/resources/sink-config.yml new file mode 100644 index 0000000000..596006a2a1 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/test/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: redisSink + appId: 5031 + userName: redisSinkUser + passWord: redisPassWord +connectorConfig: + connectorName: redisSink + server: redis://127.0.0.1:6379 + topic: SinkTopic + diff --git a/eventmesh-connectors/eventmesh-connector-redis/src/test/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-redis/src/test/resources/source-config.yml new file mode 100644 index 0000000000..5d31ad0fcb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-redis/src/test/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: redisSource + appId: 5032 + userName: redisSourceUser + passWord: redisPassWord +connectorConfig: + connectorName: redisSource + server: redis://127.0.0.1:6379 + topic: SourceTopic diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/build.gradle b/eventmesh-connectors/eventmesh-connector-rocketmq/build.gradle new file mode 100644 index 0000000000..769e9c6cf8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/build.gradle @@ -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. + */ + +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-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 { + api project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation project(":eventmesh-common") + implementation rocketmq + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-junit-jupiter" +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/gradle.properties b/eventmesh-connectors/eventmesh-connector-rocketmq/gradle.properties new file mode 100644 index 0000000000..8545888587 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/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. +# +rocketmq_version=4.9.5 +pluginType=connector +pluginName=rocketmq \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/RocketMQServerConfig.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/RocketMQServerConfig.java new file mode 100644 index 0000000000..4dc574cda2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/config/RocketMQServerConfig.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.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class RocketMQServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; + +} diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/server/RocketMQConnectServer.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/server/RocketMQConnectServer.java new file mode 100644 index 0000000000..98fd225ba8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/server/RocketMQConnectServer.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.connector.rocketmq.server; + +import org.apache.eventmesh.connector.rocketmq.config.RocketMQServerConfig; +import org.apache.eventmesh.connector.rocketmq.sink.connector.RocketMQSinkConnector; +import org.apache.eventmesh.connector.rocketmq.source.connector.RocketMQSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RocketMQConnectServer { + + public static void main(String[] args) throws Exception { + + RocketMQServerConfig serverConfig = ConfigUtil.parse(RocketMQServerConfig.class, "server-config.yml"); + + if (serverConfig.isSourceEnable()) { + Application rocketmqSourceApp = new Application(); + rocketmqSourceApp.run(RocketMQSourceConnector.class); + } + + if (serverConfig.isSinkEnable()) { + Application rocketmqSinkApp = new Application(); + rocketmqSinkApp.run(RocketMQSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/config/RocketMQSinkConfig.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/sink/config/RocketMQSinkConfig.java similarity index 84% rename from eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/config/RocketMQSinkConfig.java rename to eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/sink/config/RocketMQSinkConfig.java index 0b90fb3990..bc4191c9bf 100644 --- a/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/config/RocketMQSinkConfig.java +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/sink/config/RocketMQSinkConfig.java @@ -15,15 +15,17 @@ * limitations under the License. */ -package org.apache.eventmesh.sink.connector.rocketmq.config; +package org.apache.eventmesh.connector.rocketmq.sink.config; import org.apache.eventmesh.openconnect.api.config.SinkConfig; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = true) public class RocketMQSinkConfig extends SinkConfig { - public ConnectorConfig connectorConfig; + public SinkConnectorConfig connectorConfig; } diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..034dd7ce0c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/sink/config/SinkConnectorConfig.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.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String nameServer; + + private String topic; +} diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/sink/connector/RocketMQSinkConnector.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/sink/connector/RocketMQSinkConnector.java new file mode 100644 index 0000000000..a63d92d7f5 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/sink/connector/RocketMQSinkConnector.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.connector.rocketmq.sink.connector; + +import org.apache.eventmesh.connector.rocketmq.sink.config.RocketMQSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.rocketmq.client.producer.DefaultMQProducer; +import org.apache.rocketmq.client.producer.SendResult; +import org.apache.rocketmq.common.message.Message; +import org.apache.rocketmq.common.message.MessageAccessor; + +import java.util.List; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RocketMQSinkConnector implements Sink { + + private RocketMQSinkConfig sinkConfig; + + private final DefaultMQProducer producer = new DefaultMQProducer(); + + @Override + public Class configClass() { + return RocketMQSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for rocketmq source connector + this.sinkConfig = (RocketMQSinkConfig) config; + producer.setProducerGroup(sinkConfig.getPubSubConfig().getGroup()); + producer.setNamesrvAddr(sinkConfig.getConnectorConfig().getNameServer()); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + // init config for rocketmq source connector + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (RocketMQSinkConfig) sinkConnectorContext.getSinkConfig(); + producer.setProducerGroup(sinkConfig.getPubSubConfig().getGroup()); + producer.setNamesrvAddr(sinkConfig.getConnectorConfig().getNameServer()); + } + + @Override + public void start() throws Exception { + producer.start(); + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + producer.shutdown(); + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + Message message = convertRecordToMessage(connectRecord); + try { + SendResult sendResult = producer.send(message); + } catch (InterruptedException e) { + Thread currentThread = Thread.currentThread(); + log.warn("[RocketMQSinkConnector] Interrupting thread {} due to exception {}", + currentThread.getName(), e.getMessage()); + currentThread.interrupt(); + } catch (Exception e) { + log.error("[RocketMQSinkConnector] sendResult has error : ", e); + } + } + } + + public Message convertRecordToMessage(ConnectRecord connectRecord) { + Message message = new Message(); + message.setTopic(this.sinkConfig.getConnectorConfig().getTopic()); + message.setBody((byte[]) connectRecord.getData()); + for (String key : connectRecord.getExtensions().keySet()) { + MessageAccessor.putProperty(message, key, connectRecord.getExtension(key)); + } + return message; + } +} diff --git a/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/config/RocketMQSourceConfig.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/source/config/RocketMQSourceConfig.java similarity index 83% rename from eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/config/RocketMQSourceConfig.java rename to eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/source/config/RocketMQSourceConfig.java index 204cd96182..43a74fabd4 100644 --- a/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/config/RocketMQSourceConfig.java +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/source/config/RocketMQSourceConfig.java @@ -15,14 +15,16 @@ * limitations under the License. */ -package org.apache.eventmesh.source.connector.rocketmq.config; +package org.apache.eventmesh.connector.rocketmq.source.config; import org.apache.eventmesh.openconnect.api.config.SourceConfig; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = true) public class RocketMQSourceConfig extends SourceConfig { - public ConnectorConfig connectorConfig; + public SourceConnectorConfig connectorConfig; } diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..1dc8a0d5c9 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/source/config/SourceConnectorConfig.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.source.config; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private String nameserver; + + private String topic; + + private long commitOffsetIntervalMs = 5 * 1000; +} diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/source/connector/RocketMQSourceConnector.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/source/connector/RocketMQSourceConnector.java new file mode 100644 index 0000000000..8023be479f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/java/org/apache/eventmesh/connector/rocketmq/source/connector/RocketMQSourceConnector.java @@ -0,0 +1,304 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.source.connector; + +import org.apache.eventmesh.connector.rocketmq.source.config.RocketMQSourceConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.OffsetStorageReader; + +import org.apache.rocketmq.client.consumer.AllocateMessageQueueStrategy; +import org.apache.rocketmq.client.consumer.DefaultLitePullConsumer; +import org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely; +import org.apache.rocketmq.client.exception.MQBrokerException; +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.message.MessageQueue; +import org.apache.rocketmq.common.protocol.body.Connection; +import org.apache.rocketmq.common.protocol.body.ConsumerConnection; +import org.apache.rocketmq.remoting.exception.RemotingException; +import org.apache.rocketmq.tools.admin.DefaultMQAdminExt; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RocketMQSourceConnector implements Source { + + private RocketMQSourceConfig sourceConfig; + + private OffsetStorageReader offsetStorageReader; + + private DefaultMQAdminExt srcMQAdminExt; + + // message queue divided strategy + private final AllocateMessageQueueStrategy allocateMessageQueueStrategy = new AllocateMessageQueueAveragely(); + + private final DefaultLitePullConsumer consumer = new DefaultLitePullConsumer(); + + private final ScheduledExecutorService commitOffsetScheduleService = Executors.newSingleThreadScheduledExecutor(); + + private final ConcurrentHashMap> prepareCommitOffset = new ConcurrentHashMap<>(); + + private ConcurrentHashMap> queue2Offsets = new ConcurrentHashMap<>(); + + private final AtomicInteger unAckCounter = new AtomicInteger(); + + @Override + public Class configClass() { + return RocketMQSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for rocketmq source connector + this.sourceConfig = (RocketMQSourceConfig) config; + consumer.setConsumerGroup(sourceConfig.getPubSubConfig().getGroup()); + consumer.setNamesrvAddr(sourceConfig.getConnectorConfig().getNameserver()); + consumer.setAutoCommit(false); + consumer.setPullBatchSize(32); + consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET); + initAdmin(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (RocketMQSourceConfig) sourceConnectorContext.getSourceConfig(); + this.offsetStorageReader = sourceConnectorContext.getOffsetStorageReader(); + consumer.setConsumerGroup(sourceConfig.getPubSubConfig().getGroup()); + consumer.setNamesrvAddr(sourceConfig.getConnectorConfig().getNameserver()); + consumer.setAutoCommit(false); + consumer.setPullBatchSize(32); + consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET); + consumer.setAllocateMessageQueueStrategy(allocateMessageQueueStrategy); + initAdmin(); + } + + private synchronized void initAdmin() throws MQClientException { + if (srcMQAdminExt == null) { + srcMQAdminExt = new DefaultMQAdminExt(); + srcMQAdminExt.setNamesrvAddr(sourceConfig.getConnectorConfig().getNameserver()); + srcMQAdminExt.setAdminExtGroup("RocketMQ-Admin"); + } + } + + @Override + public void start() throws Exception { + + consumer.start(); + srcMQAdminExt.start(); + + // commit offset with schedule task + execScheduleTask(); + // todo: we need more elegant way instead of sleep + // for rocketmq client, will delay 1 second to send heartbeat to broker, so here sleep few seconds + Thread.sleep(1500); + + List allocated = getAllocatedMessageQueue(sourceConfig.getConnectorConfig().getTopic(), + sourceConfig.getPubSubConfig().getGroup()); + + consumer.assign(allocated); + + consumer.setMessageQueueListener((topic, mqAll, mqDivided) -> { + + for (MessageQueue messageQueue : mqDivided) { + try { + Map partitionMap = new HashMap<>(); + partitionMap.put("topic", messageQueue.getTopic()); + partitionMap.put("brokerName", messageQueue.getBrokerName()); + partitionMap.put("queueId", messageQueue.getQueueId() + ""); + RecordPartition recordPartition = new RecordPartition(partitionMap); + RecordOffset recordOffset = offsetStorageReader.readOffset(recordPartition); + log.info("assigned messageQueue {}, recordOffset {}", messageQueue, recordOffset); + if (recordOffset != null) { + long pollOffset = (Long) recordOffset.getOffset().get("queueOffset"); + if (pollOffset != 0) { + consumer.seek(messageQueue, pollOffset); + } + } + } catch (MQClientException e) { + throw new RuntimeException(e); + } + } + }); + } + + private List getAllocatedMessageQueue(String topic, String group) + throws MQBrokerException, RemotingException, InterruptedException, MQClientException { + List mqAll = getMessageQueueList(topic); + List cidAll = getCidList(group); + if (cidAll != null) { + Collections.sort(mqAll); + Collections.sort(cidAll); + return allocateMessageQueueStrategy.allocate(group, consumer.buildMQClientId(), mqAll, cidAll); + } + return new ArrayList<>(); + } + + private List getCidList(String group) throws MQBrokerException, RemotingException, InterruptedException, MQClientException { + ConsumerConnection consumerConnection = srcMQAdminExt.examineConsumerConnectionInfo(group); + return consumerConnection.getConnectionSet().stream().map(Connection::getClientId).collect(Collectors.toList()); + } + + private List getMessageQueueList(String topic) throws MQClientException { + Collection messageQueueCollection = consumer.fetchMessageQueues(topic); + return new ArrayList<>(messageQueueCollection); + } + + @Override + public void commit(ConnectRecord record) { + // send success, commit offset + Map map = record.getPosition().getPartition().getPartition(); + String brokerName = (String) map.get("brokerName"); + String topic = (String) map.get("topic"); + int queueId = Integer.parseInt((String) map.get("queueId")); + MessageQueue mq = new MessageQueue(topic, brokerName, queueId); + Map offsetMap = record.getPosition().getOffset().getOffset(); + long offset = Long.parseLong((String) offsetMap.get("queueOffset")); + long canCommitOffset = removeMessage(mq, offset); + log.info("commit record {}|mq {}|canCommitOffset {}", record, mq, canCommitOffset); + // commit offset to prepareCommitOffset + commitOffset(mq, canCommitOffset); + } + + @Override + public String name() { + return this.sourceConfig.getConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + consumer.unsubscribe(sourceConfig.getConnectorConfig().getTopic()); + consumer.shutdown(); + } + + @Override + public List poll() { + List messageExts = consumer.poll(); + List connectRecords = new ArrayList<>(messageExts.size()); + for (MessageExt messageExt : messageExts) { + log.info("poll message {} from mq", messageExt); + Long timestamp = System.currentTimeMillis(); + byte[] body = messageExt.getBody(); + String bodyStr = new String(body, StandardCharsets.UTF_8); + RecordPartition recordPartition = convertToRecordPartition(messageExt.getTopic(), + messageExt.getBrokerName(), messageExt.getQueueId()); + RecordOffset recordOffset = convertToRecordOffset(messageExt.getQueueOffset()); + ConnectRecord connectRecord = new ConnectRecord(recordPartition, recordOffset, timestamp, bodyStr); + connectRecord.addExtension("topic", messageExt.getTopic()); + connectRecords.add(connectRecord); + // put to unAckMessage Map + putPulledQueueOffset(messageExt); + } + return connectRecords; + } + + public static RecordOffset convertToRecordOffset(Long offset) { + Map offsetMap = new HashMap<>(); + offsetMap.put("queueOffset", offset + ""); + return new RecordOffset(offsetMap); + } + + public static RecordPartition convertToRecordPartition(String topic, String brokerName, int queueId) { + Map map = new HashMap<>(); + map.put("topic", topic); + map.put("brokerName", brokerName); + map.put("queueId", queueId + ""); + return new RecordPartition(map); + } + + private void putPulledQueueOffset(MessageExt messageExt) { + MessageQueue mq = new MessageQueue(messageExt.getTopic(), messageExt.getBrokerName(), messageExt.getQueueId()); + TreeMap offsets = queue2Offsets.get(mq); + if (offsets == null) { + TreeMap newOffsets = new TreeMap<>(); + offsets = queue2Offsets.putIfAbsent(mq, newOffsets); + if (offsets == null) { + offsets = newOffsets; + } + } + // add to unAckMessage + offsets.put(messageExt.getQueueOffset(), messageExt); + unAckCounter.incrementAndGet(); + } + + private long removeMessage(MessageQueue mq, long offset) { + TreeMap offsets = queue2Offsets.get(mq); + if (offsets != null && !offsets.isEmpty()) { + MessageExt prev = offsets.remove(offset); + if (prev != null) { + unAckCounter.decrementAndGet(); + } + } + return offset; + } + + private void execScheduleTask() { + commitOffsetScheduleService.scheduleAtFixedRate(this::commitOffsetSchedule, sourceConfig.connectorConfig.getCommitOffsetIntervalMs(), + sourceConfig.connectorConfig.getCommitOffsetIntervalMs(), TimeUnit.MILLISECONDS); + } + + private void commitOffsetSchedule() { + + prepareCommitOffset.forEach((messageQueue, list) -> { + Iterator offsetIterator = list.iterator(); + while (offsetIterator.hasNext()) { + Map commitOffsetTable = new HashMap<>(); + commitOffsetTable.put(messageQueue, offsetIterator.next().get()); + consumer.commitSync(commitOffsetTable, false); + offsetIterator.remove(); + } + }); + } + + public void commitOffset(MessageQueue mq, long canCommitOffset) { + if (canCommitOffset == -1) { + return; + } + long nextBeginOffset = canCommitOffset + 1; + List commitOffset = prepareCommitOffset.get(mq); + if (commitOffset == null || commitOffset.isEmpty()) { + commitOffset = new ArrayList<>(); + } + commitOffset.add(new AtomicLong(nextBeginOffset)); + prepareCommitOffset.put(mq, commitOffset); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..210361dc28 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: rocketmqSink + appId: 5031 + userName: rocketmqSinkUser + passWord: rocketmqPassWord +connectorConfig: + connectorName: rocketmqSink + nameServer: 127.0.0.1:9876 + topic: TopicTest diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/resources/source-config.yml new file mode 100644 index 0000000000..7a7880b877 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/main/resources/source-config.yml @@ -0,0 +1,40 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: rocketmqSource + appId: 5032 + userName: rocketmqSourceUser + passWord: rocketmqPassWord +connectorConfig: + connectorName: rocketmqSource + nameserver: 127.0.0.1:9876 + topic: TopicTest + commitOffsetIntervalMs: 5000 +offsetStorageConfig: + offsetStorageType: nacos + offsetStorageAddr: 127.0.0.1:8848 + extensions: { + #same with topic + dataId: TopicTest, + #same with group + group: rocketmqSource + } diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/connector/rocketmq/sink/connector/RocketMQSinkConnectorTest.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/connector/rocketmq/sink/connector/RocketMQSinkConnectorTest.java new file mode 100644 index 0000000000..afd13a3f2f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/connector/rocketmq/sink/connector/RocketMQSinkConnectorTest.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.connector.rocketmq.sink.connector; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.apache.eventmesh.connector.rocketmq.sink.config.RocketMQSinkConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import org.apache.rocketmq.client.producer.DefaultMQProducer; +import org.apache.rocketmq.common.message.Message; + +import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ReflectionSupport; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class RocketMQSinkConnectorTest { + + @InjectMocks + private RocketMQSinkConnector sinkConnector; + + @Mock + private DefaultMQProducer producer; + + private static final String EXPECTED_MESSAGE = "\"testMessage\""; + + @BeforeEach + public void setUp() throws Exception { + Mockito.doNothing().when(producer).start(); + Mockito.doReturn(null).when(producer).send(Mockito.any(Message.class)); + Field field = ReflectionSupport.findFields(sinkConnector.getClass(), + (f) -> f.getName().equals("producer"), HierarchyTraversalMode.BOTTOM_UP).get(0); + field.setAccessible(true); + field.set(sinkConnector, producer); + producer.start(); + RocketMQSinkConfig sinkConfig = (RocketMQSinkConfig) ConfigUtil.parse(sinkConnector.configClass()); + sinkConnector.init(sinkConfig); + sinkConnector.start(); + } + + @Test + public void testRocketMQSinkConnector() throws Exception { + final int messageCount = 5; + sinkConnector.put(generateMockedRecords(messageCount)); + verify(producer, times(messageCount)).send(any(Message.class)); + } + + private List generateMockedRecords(final int messageCount) { + List records = new ArrayList<>(); + for (int i = 0; i < messageCount; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, System.currentTimeMillis(), + EXPECTED_MESSAGE.getBytes(StandardCharsets.UTF_8)); + connectRecord.addExtension("id", String.valueOf(UUID.randomUUID())); + records.add(connectRecord); + } + return records; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/connector/rocketmq/source/connector/RocketMQSourceConnectorTest.java b/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/connector/rocketmq/source/connector/RocketMQSourceConnectorTest.java new file mode 100644 index 0000000000..5f5e3410bf --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/java/org/apache/eventmesh/connector/rocketmq/source/connector/RocketMQSourceConnectorTest.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.connector.rocketmq.source.connector; + +import org.apache.eventmesh.connector.rocketmq.source.config.RocketMQSourceConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import org.apache.rocketmq.client.consumer.DefaultLitePullConsumer; +import org.apache.rocketmq.common.message.MessageExt; + +import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ReflectionSupport; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class RocketMQSourceConnectorTest { + + @InjectMocks + private RocketMQSourceConnector sourceConnector; + + @Mock + private DefaultLitePullConsumer consumer; + + private RocketMQSourceConfig sourceConfig; + + private static final String EXPECTED_MESSAGE = "testMessage"; + + @BeforeEach + public void setUp() throws Exception { + sourceConfig = (RocketMQSourceConfig) ConfigUtil.parse(sourceConnector.configClass()); + Mockito.doReturn(generateMockedMessages()).when(consumer).poll(); + Field field = ReflectionSupport.findFields(sourceConnector.getClass(), + (f) -> f.getName().equals("consumer"), HierarchyTraversalMode.BOTTOM_UP).get(0); + field.setAccessible(true); + field.set(sourceConnector, consumer); + } + + @Test + public void testRocketMQSourceConnectorPoll() { + List poll = sourceConnector.poll(); + poll.forEach(connectRecord -> { + Assertions.assertNotNull(connectRecord); + Assertions.assertEquals(EXPECTED_MESSAGE, connectRecord.getData()); + Assertions.assertNotNull(connectRecord.getExtension("topic")); + Assertions.assertNotNull(connectRecord.getPosition()); + Assertions.assertEquals(connectRecord.getExtension("topic"), sourceConfig.getConnectorConfig().getTopic()); + }); + } + + private List generateMockedMessages() { + final int mockCount = 5; + List messageExts = new ArrayList<>(); + for (int i = 0; i < mockCount; i++) { + MessageExt messageExt = new MessageExt(); + messageExt.setTopic(sourceConfig.getConnectorConfig().getTopic()); + messageExt.setBody(EXPECTED_MESSAGE.getBytes(StandardCharsets.UTF_8)); + messageExt.setQueueOffset(1L); + messageExt.setQueueId(2); + messageExt.setBrokerName("testBroker"); + messageExts.add(messageExt); + } + return messageExts; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/resources/sink-config.yml new file mode 100644 index 0000000000..210361dc28 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: rocketmqSink + appId: 5031 + userName: rocketmqSinkUser + passWord: rocketmqPassWord +connectorConfig: + connectorName: rocketmqSink + nameServer: 127.0.0.1:9876 + topic: TopicTest diff --git a/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/resources/source-config.yml new file mode 100644 index 0000000000..7a7880b877 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-rocketmq/src/test/resources/source-config.yml @@ -0,0 +1,40 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TopicTest + idc: FT + env: PRD + group: rocketmqSource + appId: 5032 + userName: rocketmqSourceUser + passWord: rocketmqPassWord +connectorConfig: + connectorName: rocketmqSource + nameserver: 127.0.0.1:9876 + topic: TopicTest + commitOffsetIntervalMs: 5000 +offsetStorageConfig: + offsetStorageType: nacos + offsetStorageAddr: 127.0.0.1:8848 + extensions: { + #same with topic + dataId: TopicTest, + #same with group + group: rocketmqSource + } diff --git a/eventmesh-connectors/eventmesh-connector-s3/build.gradle b/eventmesh-connectors/eventmesh-connector-s3/build.gradle new file mode 100644 index 0000000000..9d004b2f15 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-s3/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 project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation 'software.amazon.awssdk:s3' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-s3/gradle.properties b/eventmesh-connectors/eventmesh-connector-s3/gradle.properties new file mode 100644 index 0000000000..4697f2bdc2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-s3/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=s3 \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/config/S3ServerConfig.java b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/config/S3ServerConfig.java new file mode 100644 index 0000000000..f5c4371d4c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/config/S3ServerConfig.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.s3.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class S3ServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; + +} diff --git a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/server/S3ConnectServer.java b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/server/S3ConnectServer.java new file mode 100644 index 0000000000..e1b485801f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/server/S3ConnectServer.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.connector.s3.server; + +import org.apache.eventmesh.connector.s3.config.S3ServerConfig; +import org.apache.eventmesh.connector.s3.source.connector.S3SourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class S3ConnectServer { + + public static void main(String[] args) throws Exception { + S3ServerConfig s3ServerConfig = ConfigUtil.parse(S3ServerConfig.class, "server-config.yml"); + if (s3ServerConfig.isSourceEnable()) { + Application application = new Application(); + application.run(S3SourceConnector.class); + } + + if (s3ServerConfig.isSinkEnable()) { + log.error("S3 sink is not supported yet."); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/S3SourceConfig.java b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/S3SourceConfig.java new file mode 100644 index 0000000000..0f4bec5d56 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/S3SourceConfig.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.connector.s3.source.config; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; + +@Data +public class S3SourceConfig extends SourceConfig { + + private SourceConnectorConfig sourceConnectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/SourceConnectorConfig.java new file mode 100644 index 0000000000..2c9cb5a80c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/config/SourceConnectorConfig.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.connector.s3.source.config; + +import java.util.Map; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + + private String region; + + private String bucket; + + private String accessKey; + + private String secretKey; + + private String fileName; + + /** + * The schema for the data to be read from S3. + */ + private Map schema; + + /** + * The maximum number of records that should be returned in each batch poll. + */ + private Integer batchSize = 20; + + /** + * The maximum ms to wait for request futures to complete. + */ + private long timeout = 3000; +} diff --git a/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/connector/S3SourceConnector.java b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/connector/S3SourceConnector.java new file mode 100644 index 0000000000..83ac15398b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-s3/src/main/java/org/apache/eventmesh/connector/s3/source/connector/S3SourceConnector.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.connector.s3.source.connector; + +import org.apache.eventmesh.connector.s3.source.config.S3SourceConfig; +import org.apache.eventmesh.connector.s3.source.config.SourceConnectorConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +import lombok.extern.slf4j.Slf4j; + +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.core.ResponseBytes; +import software.amazon.awssdk.core.async.AsyncResponseTransformer; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3AsyncClient; +import software.amazon.awssdk.services.s3.model.GetObjectRequest; +import software.amazon.awssdk.services.s3.model.GetObjectResponse; +import software.amazon.awssdk.services.s3.model.HeadObjectResponse; + +@Slf4j +public class S3SourceConnector implements Source { + + public static final String REGION = "region"; + + public static final String BUCKET = "bucket"; + + public static final String FILE_NAME = "fileName"; + + public static final String POSITION = "position"; + + private S3SourceConfig sourceConfig; + + private SourceConnectorConfig sourceConnectorConfig; + + private int eachRecordSize; + + private long fileSize; + + private S3AsyncClient s3Client; + + private long position; + + @Override + public Class configClass() { + return S3SourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for s3 source connector + this.sourceConfig = (S3SourceConfig) config; + doInit(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + this.sourceConfig = (S3SourceConfig) sourceConnectorContext.getSourceConfig(); + doInit(); + } + + private void doInit() { + this.sourceConnectorConfig = this.sourceConfig.getSourceConnectorConfig(); + this.eachRecordSize = calculateEachRecordSize(); + AwsBasicCredentials basicCredentials = AwsBasicCredentials.create(this.sourceConnectorConfig.getAccessKey(), + this.sourceConnectorConfig.getSecretKey()); + this.s3Client = S3AsyncClient.builder().credentialsProvider(() -> basicCredentials) + .region(Region.of(this.sourceConnectorConfig.getRegion())).build(); + } + + private int calculateEachRecordSize() { + Optional sum = this.sourceConnectorConfig.getSchema().values().stream().reduce((x, y) -> x + y); + return sum.orElse(0); + } + + @Override + public void start() throws Exception { + CompletableFuture headObjectResponseCompletableFuture = this.s3Client.headObject( + builder -> builder.bucket(this.sourceConnectorConfig.getBucket()).key(this.sourceConnectorConfig.getFileName())); + headObjectResponseCompletableFuture.get(this.sourceConnectorConfig.getTimeout(), TimeUnit.MILLISECONDS); + this.fileSize = headObjectResponseCompletableFuture.get().contentLength(); + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.getSourceConnectorConfig().getConnectorName(); + } + + @Override + public void stop() throws Exception { + + } + + @Override + public List poll() { + if (this.position >= this.fileSize) { + return Collections.EMPTY_LIST; + } + long startPosition = this.position; + long endPosition = Math.min(this.fileSize, this.position + this.eachRecordSize * this.sourceConnectorConfig.getBatchSize()) - 1; + GetObjectRequest request = GetObjectRequest.builder().bucket(this.sourceConnectorConfig.getBucket()) + .key(this.sourceConnectorConfig.getFileName()) + .range("bytes=" + startPosition + "-" + endPosition).build(); + ResponseBytes resp; + try { + resp = this.s3Client.getObject(request, AsyncResponseTransformer.toBytes()) + .get(this.sourceConnectorConfig.getTimeout(), TimeUnit.MILLISECONDS); + } catch (Exception e) { + log.error("poll records from S3 file, poll range {}-{}, but failed", startPosition, endPosition, e); + return Collections.EMPTY_LIST; + } + byte[] bytes = resp.asByteArray(); + List records = new ArrayList<>(bytes.length / this.eachRecordSize); + for (int i = 0; i < bytes.length; i += this.eachRecordSize) { + byte[] body = new byte[this.eachRecordSize]; + System.arraycopy(bytes, i, body, 0, this.eachRecordSize); + this.position += this.eachRecordSize; + ConnectRecord record = new ConnectRecord(getRecordPartition(), getRecordOffset(), System.currentTimeMillis(), body); + records.add(record); + } + return records; + } + + private RecordPartition getRecordPartition() { + Map map = new HashMap<>(); + map.put(REGION, this.sourceConnectorConfig.getRegion()); + map.put(BUCKET, this.sourceConnectorConfig.getBucket()); + map.put(FILE_NAME, this.sourceConnectorConfig.getFileName()); + return new RecordPartition(map); + } + + private RecordOffset getRecordOffset() { + Map map = new HashMap<>(); + map.put(POSITION, String.valueOf(this.position)); + return new RecordOffset(map); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-s3/src/test/java/org/apache/eventmesh/connector/s3/source/S3SourceConnectorTest.java b/eventmesh-connectors/eventmesh-connector-s3/src/test/java/org/apache/eventmesh/connector/s3/source/S3SourceConnectorTest.java new file mode 100644 index 0000000000..d6bb08d421 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-s3/src/test/java/org/apache/eventmesh/connector/s3/source/S3SourceConnectorTest.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.connector.s3.source; + +import org.apache.eventmesh.connector.s3.source.config.S3SourceConfig; +import org.apache.eventmesh.connector.s3.source.config.SourceConnectorConfig; +import org.apache.eventmesh.connector.s3.source.connector.S3SourceConnector; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.core.async.AsyncRequestBody; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3AsyncClient; +import software.amazon.awssdk.services.s3.model.PutObjectRequest; + +@Disabled +public class S3SourceConnectorTest { + + private static final S3SourceConfig sourceConfig; + + private static final SourceConnectorConfig SOURCE_CONNECTOR_CONFIG; + + private static final Map schema; + + private static final int eachRecordSize; + + static { + sourceConfig = new S3SourceConfig(); + SOURCE_CONNECTOR_CONFIG = new SourceConnectorConfig(); + SOURCE_CONNECTOR_CONFIG.setConnectorName("S3SourceConnector"); + SOURCE_CONNECTOR_CONFIG.setRegion("ap-southeast-1"); + SOURCE_CONNECTOR_CONFIG.setBucket("event-mesh-bucket"); + SOURCE_CONNECTOR_CONFIG.setAccessKey("access-key"); + SOURCE_CONNECTOR_CONFIG.setSecretKey("secret-key"); + + SOURCE_CONNECTOR_CONFIG.setFileName("test-file"); + + schema = new HashMap<>(); + schema.put("id", 4); + schema.put("body", 16); + schema.put("time", 8); + + eachRecordSize = schema.values().stream().reduce((x, y) -> x + y).orElse(0); + SOURCE_CONNECTOR_CONFIG.setSchema(schema); + sourceConfig.setSourceConnectorConfig(SOURCE_CONNECTOR_CONFIG); + } + + private S3AsyncClient s3Client; + + @BeforeEach + public void setUp() throws Exception { + AwsBasicCredentials basicCredentials = AwsBasicCredentials.create(this.SOURCE_CONNECTOR_CONFIG.getAccessKey(), + this.SOURCE_CONNECTOR_CONFIG.getSecretKey()); + this.s3Client = S3AsyncClient.builder().credentialsProvider(() -> basicCredentials) + .region(Region.of(this.SOURCE_CONNECTOR_CONFIG.getRegion())).build(); + + // write mocked data + this.writeMockedRecords(200); + } + + @AfterEach + public void tearDown() throws Exception { + // clear file + this.s3Client.deleteObject(builder -> builder.bucket(this.SOURCE_CONNECTOR_CONFIG.getBucket()) + .key(this.SOURCE_CONNECTOR_CONFIG.getFileName()).build()).get(); + } + + @Test + public void testS3SourceConnector() throws Exception { + S3SourceConnector s3SourceConnector = new S3SourceConnector(); + s3SourceConnector.init(sourceConfig); + s3SourceConnector.start(); + int expectedId = 0; + while (true) { + List connectRecords = s3SourceConnector.poll(); + if (connectRecords.isEmpty()) { + break; + } + Assertions.assertEquals(20, connectRecords.size()); + for (ConnectRecord connectRecord : connectRecords) { + byte[] data = (byte[]) connectRecord.getData(); + Assertions.assertEquals(eachRecordSize, data.length); + ByteBuffer byteBuffer = ByteBuffer.wrap(data); + int id = byteBuffer.getInt(); + Assertions.assertEquals(expectedId++, id); + } + } + + } + + private void writeMockedRecords(int count) throws Exception { + ByteBuffer bytes = ByteBuffer.allocate(count * eachRecordSize); + ByteBuffer body = ByteBuffer.allocate(16); + body.putLong(13L); + body.putLong(13L); + body.flip(); + for (int i = 0; i < count; i++) { + bytes.putInt(i); + bytes.put(body); + body.flip(); + bytes.putLong(System.currentTimeMillis()); + } + PutObjectRequest putObjectRequest = PutObjectRequest.builder() + .bucket(SOURCE_CONNECTOR_CONFIG.getBucket()).key(SOURCE_CONNECTOR_CONFIG.getFileName()).build(); + AsyncRequestBody requestBody = AsyncRequestBody.fromBytes(bytes.array()); + this.s3Client.putObject(putObjectRequest, requestBody).get(); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-slack/build.gradle b/eventmesh-connectors/eventmesh-connector-slack/build.gradle new file mode 100644 index 0000000000..ad66b78b96 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/build.gradle @@ -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. + */ + +configurations { + implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' + implementation.exclude group: 'log4j', module: 'log4j' + testImplementation.exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j' +} + +dependencies { + implementation project(":eventmesh-common") + implementation project(":eventmesh-sdks:eventmesh-sdk-java") + implementation project(":eventmesh-openconnect:eventmesh-openconnect-java") + + implementation "com.slack.api:bolt:1.1.+" + implementation 'com.google.guava:guava' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-junit-jupiter" +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-slack/gradle.properties b/eventmesh-connectors/eventmesh-connector-slack/gradle.properties new file mode 100644 index 0000000000..c6c4b2e224 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/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=slack \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/config/SlackConnectServerConfig.java b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/config/SlackConnectServerConfig.java new file mode 100644 index 0000000000..515c5af6c7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/config/SlackConnectServerConfig.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.slack.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class SlackConnectServerConfig extends Config { + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/server/SlackConnectServer.java b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/server/SlackConnectServer.java new file mode 100644 index 0000000000..b59f0657ac --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/server/SlackConnectServer.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.connector.slack.server; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.slack.config.SlackConnectServerConfig; +import org.apache.eventmesh.connector.slack.sink.connector.SlackSinkConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +public class SlackConnectServer { + + public static void main(String[] args) throws Exception { + + SlackConnectServerConfig slackConnectServerConfig = ConfigUtil.parse(SlackConnectServerConfig.class, + Constants.CONNECT_SERVER_CONFIG_FILE_NAME); + + if (slackConnectServerConfig.isSinkEnable()) { + Application application = new Application(); + application.run(SlackSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..41884a94a1 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/sink/config/SinkConnectorConfig.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.slack.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String appToken; + + private String channelId; +} diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/sink/config/SlackSinkConfig.java b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/sink/config/SlackSinkConfig.java new file mode 100644 index 0000000000..016cd9ae97 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/sink/config/SlackSinkConfig.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.slack.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class SlackSinkConfig extends SinkConfig { + + private SinkConnectorConfig sinkConnectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/sink/connector/SlackSinkConnector.java b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/sink/connector/SlackSinkConnector.java new file mode 100644 index 0000000000..a026f2aa22 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/main/java/org/apache/eventmesh/connector/slack/sink/connector/SlackSinkConnector.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.connector.slack.sink.connector; + +import org.apache.eventmesh.connector.slack.sink.config.SlackSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Objects; + +import com.slack.api.Slack; +import com.slack.api.methods.MethodsClient; +import com.slack.api.methods.response.chat.ChatPostMessageResponse; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +/** + * Slack sink connector. + * Slack doc: ... + */ +@Slf4j +public class SlackSinkConnector implements Sink { + + private SlackSinkConfig sinkConfig; + + private volatile boolean isRunning = false; + + private MethodsClient client; + + @Override + public Class configClass() { + return SlackSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for dingding sink connector + this.sinkConfig = (SlackSinkConfig) config; + this.client = Slack.getInstance().methods(); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + // init config for dingding source connector + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (SlackSinkConfig) sinkConnectorContext.getSinkConfig(); + this.client = Slack.getInstance().methods(); + } + + @Override + public void start() { + isRunning = true; + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getSinkConnectorConfig().getConnectorName(); + } + + @Override + public void stop() { + isRunning = false; + } + + public boolean isRunning() { + return isRunning; + } + + @SneakyThrows + @Override + public void put(List sinkRecords) { + for (ConnectRecord record : sinkRecords) { + publishMessage(record); + } + } + + private void publishMessage(ConnectRecord record) { + try { + ChatPostMessageResponse response = client.chatPostMessage(r -> r + .token(sinkConfig.getSinkConnectorConfig().getAppToken()) + .channel(sinkConfig.getSinkConnectorConfig().getChannelId()) + .text(new String((byte[]) record.getData()))); + if (Objects.nonNull(response) && StringUtils.isNotBlank(response.getError())) { + throw new IllegalAccessException(response.getError()); + } + } catch (Exception e) { + log.error("Send message to slack error.", e); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-slack/src/main/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/main/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-slack/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..062eaf3495 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-SLACK + idc: FT + env: PRD + group: slackSink + appId: 5034 + userName: slackSinkUser + passWord: slackPassWord +sinkConnectorConfig: + connectorName: slackSink + appToken: slackAppToken + channelId: slackChannelId diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/test/java/org/apache/eventmesh/connector/slack/sink/connector/SlackSinkConnectorTest.java b/eventmesh-connectors/eventmesh-connector-slack/src/test/java/org/apache/eventmesh/connector/slack/sink/connector/SlackSinkConnectorTest.java new file mode 100644 index 0000000000..3f0a32755f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/test/java/org/apache/eventmesh/connector/slack/sink/connector/SlackSinkConnectorTest.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.connector.slack.sink.connector; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.apache.eventmesh.connector.slack.sink.config.SlackSinkConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ReflectionSupport; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.slack.api.RequestConfigurator; +import com.slack.api.methods.MethodsClient; +import com.slack.api.methods.response.chat.ChatPostMessageResponse; + +@ExtendWith(MockitoExtension.class) +public class SlackSinkConnectorTest { + + private SlackSinkConnector sinkConnector; + + @Mock + private MethodsClient client; + + @BeforeEach + public void setUp() throws Exception { + sinkConnector = new SlackSinkConnector(); + SlackSinkConfig sinkConfig = (SlackSinkConfig) ConfigUtil.parse(sinkConnector.configClass()); + sinkConnector.init(sinkConfig); + doReturn(new ChatPostMessageResponse()) + .when(client).chatPostMessage(any(RequestConfigurator.class)); + Field clientField = ReflectionSupport.findFields(sinkConnector.getClass(), + (f) -> f.getName().equals("client"), + HierarchyTraversalMode.BOTTOM_UP).get(0); + clientField.setAccessible(true); + clientField.set(sinkConnector, client); + sinkConnector.start(); + } + + @Test + public void testSendMessageToSlack() throws Exception { + final int times = 3; + List records = new ArrayList<>(); + for (int i = 0; i < times; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, + System.currentTimeMillis(), "Hello, EventMesh!".getBytes(StandardCharsets.UTF_8)); + records.add(connectRecord); + } + sinkConnector.put(records); + verify(client, times(times)).chatPostMessage(any(RequestConfigurator.class)); + } + + @AfterEach + public void tearDown() { + sinkConnector.stop(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/test/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-slack/src/test/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/test/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-slack/src/test/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-slack/src/test/resources/sink-config.yml new file mode 100644 index 0000000000..062eaf3495 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-slack/src/test/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-SLACK + idc: FT + env: PRD + group: slackSink + appId: 5034 + userName: slackSinkUser + passWord: slackPassWord +sinkConnectorConfig: + connectorName: slackSink + appToken: slackAppToken + channelId: slackChannelId diff --git a/eventmesh-connectors/eventmesh-connector-spring/build.gradle b/eventmesh-connectors/eventmesh-connector-spring/build.gradle new file mode 100644 index 0000000000..48459b9004 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/build.gradle @@ -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. + */ + +configurations { + implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' + implementation.exclude group: 'log4j', module: 'log4j' + implementation.exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j' + testImplementation.exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j' +} + +dependencies { + api project(":eventmesh-openconnect:eventmesh-openconnect-java") + implementation project(":eventmesh-common") + implementation project(":eventmesh-sdks:eventmesh-sdk-java") + implementation "org.springframework.boot:spring-boot-starter:$spring_boot_version" + implementation "org.springframework.boot:spring-boot-starter-validation:$spring_boot_version" + implementation "org.springframework:spring-messaging:$spring_version" + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-junit-jupiter" +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-spring/gradle.properties b/eventmesh-connectors/eventmesh-connector-spring/gradle.properties new file mode 100644 index 0000000000..3ff99a1c80 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/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. +# +spring_boot_version=2.5.9 +spring_version=5.3.20 +pluginType=connector +pluginName=spring \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/common/SpringApplicationContextHolder.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/common/SpringApplicationContextHolder.java new file mode 100644 index 0000000000..bb07baa94f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/common/SpringApplicationContextHolder.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.connector.spring.common; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +public class SpringApplicationContextHolder implements ApplicationContextAware { + + private static ApplicationContext applicationContext; + + public static boolean isStarted() { + return applicationContext != null; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringApplicationContextHolder.applicationContext = applicationContext; + } + + public static T getBean(Class clazz) { + return applicationContext.getBean(clazz); + } + + public static Object getBean(String beanName) { + return applicationContext.getBean(beanName); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/EventMeshAutoConfiguration.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/EventMeshAutoConfiguration.java new file mode 100644 index 0000000000..12f56a501e --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/EventMeshAutoConfiguration.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.spring.config; + +import org.apache.eventmesh.connector.spring.common.SpringApplicationContextHolder; +import org.apache.eventmesh.connector.spring.server.SpringConnectServer; +import org.apache.eventmesh.connector.spring.sink.EventMeshListenerBeanPostProcessor; +import org.apache.eventmesh.connector.spring.sink.connector.SpringSinkConnector; +import org.apache.eventmesh.connector.spring.source.connector.SpringSourceConnector; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Spring auto configuration. + */ +@Configuration +public class EventMeshAutoConfiguration { + + public static final String SPRING_SOURCE_CONNECTOR_BEAN_NAME = "springSourceConnector"; + public static final String SPRING_SINK_CONNECTOR_BEAN_NAME = "springSinkConnector"; + public static final String SPRING_CONNECT_SERVER_BEAN_NAME = "springConnectServer"; + public static final String SPRING_APPLICATION_CONTEXT_HOLDER = "springApplicationContextHolder"; + public static final String EVENTMESH_LISTENER_BEAN_POST_PROCESSOR = "eventMeshListenerBeanPostProcessor"; + + @Bean(name = SPRING_SOURCE_CONNECTOR_BEAN_NAME) + @ConditionalOnMissingBean(name = SPRING_SOURCE_CONNECTOR_BEAN_NAME) + public SpringSourceConnector springSourceConnector() { + return new SpringSourceConnector(); + } + + @Bean(name = SPRING_SINK_CONNECTOR_BEAN_NAME) + @ConditionalOnMissingBean(name = SPRING_SINK_CONNECTOR_BEAN_NAME) + public SpringSinkConnector springSinkConnector() { + return new SpringSinkConnector(); + } + + @Bean(name = SPRING_CONNECT_SERVER_BEAN_NAME) + @ConditionalOnMissingBean(name = SPRING_CONNECT_SERVER_BEAN_NAME) + public SpringConnectServer springConnectServer() { + return new SpringConnectServer(); + } + + @Bean(name = SPRING_APPLICATION_CONTEXT_HOLDER) + @ConditionalOnMissingBean(name = SPRING_APPLICATION_CONTEXT_HOLDER) + public SpringApplicationContextHolder springApplicationContextHolder() { + return new SpringApplicationContextHolder(); + } + + @Bean(name = EVENTMESH_LISTENER_BEAN_POST_PROCESSOR) + @ConditionalOnMissingBean(name = EVENTMESH_LISTENER_BEAN_POST_PROCESSOR) + public EventMeshListenerBeanPostProcessor eventMeshListenerBeanPostProcessor() { + return new EventMeshListenerBeanPostProcessor(); + } + +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/SpringConnectServerConfig.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/SpringConnectServerConfig.java new file mode 100644 index 0000000000..7eb2009fbd --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/config/SpringConnectServerConfig.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.spring.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class SpringConnectServerConfig extends Config { + + private boolean sourceEnable; + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/server/SpringConnectServer.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/server/SpringConnectServer.java new file mode 100644 index 0000000000..f176200ae4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/server/SpringConnectServer.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.connector.spring.server; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.spring.config.SpringConnectServerConfig; +import org.apache.eventmesh.connector.spring.source.connector.SpringSourceConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.CommandLineRunner; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SpringConnectServer implements CommandLineRunner { + + private static final String SPRING_SOURCE = "springSource"; + + @Override + public void run(String... args) throws Exception { + SpringConnectServerConfig springConnectServerConfig = ConfigUtil.parse(SpringConnectServerConfig.class, + Constants.CONNECT_SERVER_CONFIG_FILE_NAME); + + if (springConnectServerConfig.isSourceEnable()) { + Map extensions = new HashMap<>(); + extensions.put(Application.CREATE_EXTENSION_KEY, SPRING_SOURCE); + Application application = new Application(extensions); + application.run(SpringSourceConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshConsumerMetadata.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshConsumerMetadata.java new file mode 100644 index 0000000000..1585480c8d --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshConsumerMetadata.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.spring.sink; + +import java.lang.reflect.Method; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class EventMeshConsumerMetadata { + + private Object bean; + + private Method method; + + private EventMeshListener annotation; + +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListener.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListener.java new file mode 100644 index 0000000000..e2a850a219 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListener.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.connector.spring.sink; + +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; + +import org.springframework.stereotype.Component; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Component +public @interface EventMeshListener { + + /** + * The requestTimeout of client,it is 5s by default. + */ + int requestTimeout() default 5; +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListenerBeanPostProcessor.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListenerBeanPostProcessor.java new file mode 100644 index 0000000000..b36e308412 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/EventMeshListenerBeanPostProcessor.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.connector.spring.sink; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.connector.spring.config.SpringConnectServerConfig; +import org.apache.eventmesh.connector.spring.sink.connector.SpringSinkConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.springframework.aop.support.AopUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.util.ReflectionUtils; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EventMeshListenerBeanPostProcessor implements ApplicationContextAware, + CommandLineRunner, BeanPostProcessor { + + private static final String SPRING_SINK = "springSink"; + + private static final ThreadPoolExecutor executor = ThreadPoolFactory.createThreadPoolExecutor( + Runtime.getRuntime().availableProcessors() * 2, + Runtime.getRuntime().availableProcessors() * 2, + "EventMesh-MessageListenerBeanPostProcessor-"); + + private ApplicationContext applicationContext; + + private List metadataList = new ArrayList<>(); + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + Class targetClass = AopUtils.isAopProxy(bean) ? AopUtils.getTargetClass(bean) : bean.getClass(); + ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() { + + @Override + public void doWith(final Method method) throws IllegalArgumentException, IllegalAccessException { + EventMeshListener annotation = AnnotatedElementUtils.findMergedAnnotation(method, EventMeshListener.class); + if (annotation == null || method.isBridge()) { + return; + } + metadataList.add(new EventMeshConsumerMetadata(bean, method, annotation)); + } + }); + return bean; + } + + @Override + public void run(String... args) throws Exception { + runSinkConnector(); + metadataList.forEach(metadata -> { + Object bean = metadata.getBean(); + Method method = metadata.getMethod(); + EventMeshListener annotation = metadata.getAnnotation(); + SpringSinkConnector sinkConnector = applicationContext.getBean(SpringSinkConnector.class); + executor.execute(() -> { + ConnectRecord poll; + while (sinkConnector.isRunning()) { + try { + poll = sinkConnector.getQueue().poll(annotation.requestTimeout(), TimeUnit.SECONDS); + if (null == poll || null == poll.getData()) { + continue; + } + String messageBody = new String((byte[]) poll.getData()); + Type[] parameterizedTypes = method.getGenericParameterTypes(); + if (parameterizedTypes.length == 0) { + throw new IllegalStateException("There has not any arguments for consumer method."); + } + if (parameterizedTypes.length > 1) { + throw new IllegalStateException("There has more than one arguments for consumer method."); + } + Class rawType; + if (parameterizedTypes[0] instanceof Class) { + rawType = (Class) parameterizedTypes[0]; + } else { + throw new IllegalStateException( + "The arguments type for consumer method can't cast to be Class and ParameterizedTypeImpl"); + } + if (rawType == String.class) { + metadata.getMethod().invoke(bean, messageBody); + } else { + metadata.getMethod().invoke(bean, JsonUtils.parseObject(messageBody, parameterizedTypes[0])); + } + } catch (Exception e) { + log.warn("Consume snapshot event error", e); + } + } + }); + }); + } + + @SneakyThrows + public void runSinkConnector() { + SpringConnectServerConfig springConnectServerConfig = ConfigUtil.parse(SpringConnectServerConfig.class, + Constants.CONNECT_SERVER_CONFIG_FILE_NAME); + + if (springConnectServerConfig.isSinkEnable()) { + Map extensions = new HashMap<>(); + extensions.put(Application.CREATE_EXTENSION_KEY, SPRING_SINK); + Application application = new Application(extensions); + application.run(SpringSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/config/SpringSinkConfig.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/config/SpringSinkConfig.java new file mode 100644 index 0000000000..aff0d8a0f3 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/config/SpringSinkConfig.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.connector.spring.sink.config; + +import org.apache.eventmesh.connector.spring.sink.connector.SinkConnectorConfig; +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class SpringSinkConfig extends SinkConfig { + + private SinkConnectorConfig sinkConnectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SinkConnectorConfig.java new file mode 100644 index 0000000000..a71c4ab66c --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SinkConnectorConfig.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.spring.sink.connector; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnector.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnector.java new file mode 100644 index 0000000000..648e1f8071 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnector.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.connector.spring.sink.connector; + +import org.apache.eventmesh.connector.spring.sink.config.SpringSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import lombok.extern.slf4j.Slf4j; + +/** + * Spring sink connector + */ +@Slf4j +public class SpringSinkConnector implements Sink { + + private SpringSinkConfig sinkConfig; + + private BlockingQueue queue; + + private volatile boolean isRunning = false; + + @Override + public Class configClass() { + return SpringSinkConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for spring sink connector + this.sinkConfig = (SpringSinkConfig) config; + this.queue = new LinkedBlockingQueue<>(1000); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + // init config for openfunction source connector + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (SpringSinkConfig) sinkConnectorContext.getSinkConfig(); + this.queue = new LinkedBlockingQueue<>(1000); + } + + @Override + public void start() throws Exception { + isRunning = true; + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getSinkConnectorConfig().getConnectorName(); + } + + @Override + public void stop() throws Exception { + + } + + public boolean isRunning() { + return isRunning; + } + + public BlockingQueue getQueue() { + return queue; + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord connectRecord : sinkRecords) { + try { + queue.put(connectRecord); + } catch (InterruptedException e) { + Thread currentThread = Thread.currentThread(); + log.warn("[SpringSinkConnector] Interrupting thread {} due to exception {}", + currentThread.getName(), e.getMessage()); + currentThread.interrupt(); + } + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnectorCreateServiceImpl.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnectorCreateServiceImpl.java new file mode 100644 index 0000000000..e7e7b2554a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnectorCreateServiceImpl.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.connector.spring.sink.connector; + +import org.apache.eventmesh.connector.spring.common.SpringApplicationContextHolder; +import org.apache.eventmesh.connector.spring.config.EventMeshAutoConfiguration; +import org.apache.eventmesh.openconnect.api.ConnectorCreateService; +import org.apache.eventmesh.openconnect.api.sink.Sink; + +public class SpringSinkConnectorCreateServiceImpl implements ConnectorCreateService { + + @Override + public Sink create() { + if (SpringApplicationContextHolder.isStarted()) { + return (Sink) SpringApplicationContextHolder.getBean(EventMeshAutoConfiguration.SPRING_SINK_CONNECTOR_BEAN_NAME); + } + return null; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/MessageSendingOperations.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/MessageSendingOperations.java new file mode 100644 index 0000000000..a337c1cd81 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/MessageSendingOperations.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.connector.spring.source; + +import org.apache.eventmesh.openconnect.api.callback.SendMessageCallback; + +/** + * Operations for sending messages. + */ +public interface MessageSendingOperations { + + void send(Object message); + + void send(Object message, SendMessageCallback sendCallback); + +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/config/SpringSourceConfig.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/config/SpringSourceConfig.java new file mode 100644 index 0000000000..191e9b1196 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/config/SpringSourceConfig.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.connector.spring.source.config; + +import org.apache.eventmesh.connector.spring.source.connector.SourceConnectorConfig; +import org.apache.eventmesh.openconnect.api.config.SourceConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class SpringSourceConfig extends SourceConfig { + + private SourceConnectorConfig sourceConnectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SourceConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SourceConnectorConfig.java new file mode 100644 index 0000000000..242869087f --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SourceConnectorConfig.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.spring.source.connector; + +import lombok.Data; + +@Data +public class SourceConnectorConfig { + + private String connectorName; + +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnector.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnector.java new file mode 100644 index 0000000000..5f4d5c89b7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnector.java @@ -0,0 +1,183 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.spring.source.connector; + +import org.apache.eventmesh.connector.spring.source.MessageSendingOperations; +import org.apache.eventmesh.connector.spring.source.config.SpringSourceConfig; +import org.apache.eventmesh.openconnect.SourceWorker; +import org.apache.eventmesh.openconnect.api.callback.SendMessageCallback; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; +import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.springframework.beans.BeansException; +import org.springframework.boot.env.OriginTrackedMapPropertySource; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertySource; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SpringSourceConnector implements Source, MessageSendingOperations, ApplicationContextAware { + + private static final String CONNECTOR_PROPERTY_PREFIX = "eventmesh.connector."; + + private static final int DEFAULT_BATCH_SIZE = 10; + + private ApplicationContext applicationContext; + + private SpringSourceConfig sourceConfig; + + private BlockingQueue queue; + + @Override + public Class configClass() { + return SpringSourceConfig.class; + } + + @Override + public void init(Config config) throws Exception { + // init config for spring source connector + this.sourceConfig = (SpringSourceConfig) config; + this.queue = new LinkedBlockingQueue<>(1000); + } + + @Override + public void init(ConnectorContext connectorContext) throws Exception { + SourceConnectorContext sourceConnectorContext = (SourceConnectorContext) connectorContext; + // init config for spring source connector + this.sourceConfig = (SpringSourceConfig) sourceConnectorContext.getSourceConfig(); + this.queue = new LinkedBlockingQueue<>(1000); + } + + @Override + public void start() throws Exception { + + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sourceConfig.getSourceConnectorConfig().getConnectorName(); + } + + @Override + public void stop() throws Exception { + + } + + @Override + public List poll() { + List connectRecords = new ArrayList<>(DEFAULT_BATCH_SIZE); + + for (int count = 0; count < DEFAULT_BATCH_SIZE; ++count) { + try { + ConnectRecord connectRecord = queue.poll(3, TimeUnit.SECONDS); + if (connectRecord == null) { + break; + } + connectRecords.add(connectRecord); + } catch (InterruptedException e) { + Thread currentThread = Thread.currentThread(); + log.warn("[SpringSourceConnector] Interrupting thread {} due to exception {}", + currentThread.getName(), e.getMessage()); + currentThread.interrupt(); + } + } + return connectRecords; + } + + /** + * Send message. + * @param message message to send + */ + @Override + public void send(Object message) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord record = new ConnectRecord(partition, offset, System.currentTimeMillis(), message); + addSpringEnvironmentPropertyExtensions(record); + queue.offer(record); + } + + /** + * Send message with a callback. + * @param message message to send. + * @param workerCallback After the user sends the message to the Connector, + * the SourceWorker will fetch message and invoke. + */ + @Override + public void send(Object message, SendMessageCallback workerCallback) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord record = new ConnectRecord(partition, offset, System.currentTimeMillis(), message); + record.addExtension(SourceWorker.CALLBACK_EXTENSION, workerCallback); + addSpringEnvironmentPropertyExtensions(record); + queue.offer(record); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + private void addSpringEnvironmentPropertyExtensions(ConnectRecord connectRecord) { + ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext; + MutablePropertySources propertySources = context.getEnvironment().getPropertySources(); + for (PropertySource propertySource : propertySources) { + if (!(propertySource instanceof OriginTrackedMapPropertySource)) { + continue; + } + OriginTrackedMapPropertySource originTrackedMapPropertySource = + (OriginTrackedMapPropertySource) propertySource; + String[] keys = originTrackedMapPropertySource.getPropertyNames(); + for (String key : keys) { + if (!key.startsWith(CONNECTOR_PROPERTY_PREFIX)) { + continue; + } + Object value = null; + try { + value = originTrackedMapPropertySource.getProperty(key); + if (value != null) { + connectRecord.addExtension(key.replaceAll(CONNECTOR_PROPERTY_PREFIX, "").toLowerCase(), + String.valueOf(value)); + } + } catch (Throwable e) { + log.error("Put spring environment property to extension failed, key=[{}], value=[{}]", key, value); + } + } + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.java b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.java new file mode 100644 index 0000000000..573ff9ed76 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorCreateServiceImpl.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.connector.spring.source.connector; + +import org.apache.eventmesh.connector.spring.common.SpringApplicationContextHolder; +import org.apache.eventmesh.connector.spring.config.EventMeshAutoConfiguration; +import org.apache.eventmesh.openconnect.api.ConnectorCreateService; +import org.apache.eventmesh.openconnect.api.source.Source; + +public class SpringSourceConnectorCreateServiceImpl implements ConnectorCreateService { + + @Override + public Source create() { + if (SpringApplicationContextHolder.isStarted()) { + return (Source) SpringApplicationContextHolder.getBean(EventMeshAutoConfiguration.SPRING_SOURCE_CONNECTOR_BEAN_NAME); + } + return null; + } +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.api.ConnectorCreateService b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.api.ConnectorCreateService new file mode 100644 index 0000000000..1daf7796fb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.api.ConnectorCreateService @@ -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. +# + +springSink=org.apache.eventmesh.connector.spring.sink.connector.SpringSinkConnectorCreateServiceImpl +springSource=org.apache.eventmesh.connector.spring.source.connector.SpringSourceConnectorCreateServiceImpl \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/spring.factories b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..8cc07dc970 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/META-INF/spring.factories @@ -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. +# + +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.apache.eventmesh.connector.spring.config.EventMeshAutoConfiguration \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..dd5c081afa --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-SPRING + idc: FT + env: PRD + group: springSink + appId: 5033 + userName: springSinkUser + passWord: springPassWord +connectorConfig: + connectorName: springSink \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml new file mode 100644 index 0000000000..4559cd6708 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-SPRING + idc: FT + env: PRD + group: springSource + appId: 5033 + userName: springSourceUser + passWord: springPassWord +connectorConfig: + connectorName: springSource diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/test/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnectorTest.java b/eventmesh-connectors/eventmesh-connector-spring/src/test/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnectorTest.java new file mode 100644 index 0000000000..ea0ea7c359 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/test/java/org/apache/eventmesh/connector/spring/sink/connector/SpringSinkConnectorTest.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.connector.spring.sink.connector; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.apache.eventmesh.connector.spring.sink.config.SpringSinkConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class SpringSinkConnectorTest { + + @Spy + private SpringSinkConnector connector; + + @BeforeEach + public void setUp() throws Exception { + SpringSinkConfig sinkConfig = new SpringSinkConfig(); + connector.init(sinkConfig); + connector.start(); + } + + @Test + public void testSinkConnectorRunning() { + Assertions.assertTrue(connector.isRunning()); + } + + @Test + public void testProcessRecordsInSinkConnectorQueue() throws Exception { + final int count = 5; + final String message = "testMessage"; + writeMockedRecords(count, message); + BlockingQueue queue = connector.getQueue(); + Assertions.assertEquals(count, queue.size()); + for (int i = 0; i < count; i++) { + ConnectRecord poll = queue.poll(); + assertNotNull(poll); + String expectedMessage = message + i; + Assertions.assertEquals(poll.getData(), expectedMessage); + } + } + + private void writeMockedRecords(int count, String message) throws Exception { + List records = new ArrayList<>(); + for (int i = 0; i < count; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + records.add(new ConnectRecord(partition, offset, System.currentTimeMillis(), message + i)); + } + connector.put(records); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-spring/src/test/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorTest.java b/eventmesh-connectors/eventmesh-connector-spring/src/test/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorTest.java new file mode 100644 index 0000000000..65c71aea09 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-spring/src/test/java/org/apache/eventmesh/connector/spring/source/connector/SpringSourceConnectorTest.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.connector.spring.source.connector; + +import static org.mockito.Mockito.doReturn; + +import org.apache.eventmesh.connector.spring.source.config.SpringSourceConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MutablePropertySources; + +@ExtendWith(MockitoExtension.class) +public class SpringSourceConnectorTest { + + private SpringSourceConnector connector; + + @Test + public void testSpringSourceConnector() throws Exception { + ConfigurableApplicationContext context = Mockito.mock(ConfigurableApplicationContext.class); + ConfigurableEnvironment environment = Mockito.mock(ConfigurableEnvironment.class); + doReturn(new MutablePropertySources()).when(environment).getPropertySources(); + doReturn(environment).when(context).getEnvironment(); + connector = new SpringSourceConnector(); + connector.setApplicationContext(context); + SpringSourceConfig sourceConfig = new SpringSourceConfig(); + connector.init(sourceConfig); + connector.start(); + final int count = 5; + final String message = "testMessage"; + writeMockedRecords(count, message); + List connectRecords = connector.poll(); + Assertions.assertEquals(count, connectRecords.size()); + for (int i = 0; i < connectRecords.size(); i++) { + Object actualMessage = String.valueOf(connectRecords.get(i).getData()); + String expectedMessage = "testMessage" + i; + Assertions.assertEquals(expectedMessage, actualMessage); + } + } + + private void writeMockedRecords(int count, String message) { + for (int i = 0; i < count; i++) { + connector.send(message + i); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-wechat/build.gradle b/eventmesh-connectors/eventmesh-connector-wechat/build.gradle new file mode 100644 index 0000000000..c791524485 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/build.gradle @@ -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. + */ + +configurations { + implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' + implementation.exclude group: 'log4j', module: 'log4j' + testImplementation.exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j' +} + +dependencies { + implementation project(":eventmesh-common") + implementation project(":eventmesh-sdks:eventmesh-sdk-java") + implementation project(":eventmesh-openconnect:eventmesh-openconnect-java") + + implementation 'com.alibaba:fastjson' + implementation 'com.google.guava:guava' + implementation 'com.squareup.okhttp3:okhttp' + + implementation "io.netty:netty-all" + + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-junit-jupiter" + testImplementation "org.mockito:mockito-inline" +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wechat/gradle.properties b/eventmesh-connectors/eventmesh-connector-wechat/gradle.properties new file mode 100644 index 0000000000..3b209c14b4 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/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=wechat \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/config/WeChatConnectServerConfig.java b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/config/WeChatConnectServerConfig.java new file mode 100644 index 0000000000..a2634b6b49 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/config/WeChatConnectServerConfig.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.wechat.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class WeChatConnectServerConfig extends Config { + + private boolean sinkEnable; +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/server/WeChatConnectServer.java b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/server/WeChatConnectServer.java new file mode 100644 index 0000000000..0ea1927c18 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/server/WeChatConnectServer.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.connector.wechat.server; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.wechat.config.WeChatConnectServerConfig; +import org.apache.eventmesh.connector.wechat.sink.connector.WeChatSinkConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +public class WeChatConnectServer { + + public static void main(String[] args) throws Exception { + + WeChatConnectServerConfig weChatConnectServerConfig = ConfigUtil.parse(WeChatConnectServerConfig.class, + Constants.CONNECT_SERVER_CONFIG_FILE_NAME); + + if (weChatConnectServerConfig.isSinkEnable()) { + Application application = new Application(); + application.run(WeChatSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..e575e65c67 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/config/SinkConnectorConfig.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.wechat.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String appId; + + private String appSecret; +} diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/config/WeChatSinkConfig.java b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/config/WeChatSinkConfig.java new file mode 100644 index 0000000000..a77e1c77b5 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/config/WeChatSinkConfig.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.wechat.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class WeChatSinkConfig extends SinkConfig { + + private SinkConnectorConfig sinkConnectorConfig; +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/connector/TemplateMessageResponse.java b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/connector/TemplateMessageResponse.java new file mode 100644 index 0000000000..231b01c164 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/connector/TemplateMessageResponse.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.wechat.sink.connector; + +import lombok.Data; + +@Data +public class TemplateMessageResponse { + + private int errcode; + + private String errmsg; + + private String msgid; +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/connector/WeChatSinkConnector.java b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/connector/WeChatSinkConnector.java new file mode 100644 index 0000000000..1d1c3258cb --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/main/java/org/apache/eventmesh/connector/wechat/sink/connector/WeChatSinkConnector.java @@ -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 org.apache.eventmesh.connector.wechat.sink.connector; + +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.connector.wechat.sink.config.WeChatSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.commons.lang3.builder.ToStringBuilder; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import okhttp3.ResponseBody; + +/** + * WeChat sink connector. WeChat doc: ... + */ +@Slf4j +public class WeChatSinkConnector implements Sink { + + public static final Cache ACCESS_TOKEN_CACHE = CacheBuilder.newBuilder() + .initialCapacity(12) + .maximumSize(10) + .concurrencyLevel(5) + .expireAfterWrite(120, TimeUnit.MINUTES) + .build(); + + public static final String ACCESS_TOKEN_CACHE_KEY = "access_token"; + + private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; + + private static final String MESSAGE_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s"; + + private OkHttpClient okHttpClient; + + private WeChatSinkConfig sinkConfig; + + private volatile boolean isRunning = false; + + @Override + public Class configClass() { + return WeChatSinkConfig.class; + } + + @Override + public void init(Config config) { + this.sinkConfig = (WeChatSinkConfig) config; + okHttpClient = new OkHttpClient.Builder() + .connectTimeout(60, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .writeTimeout(60, TimeUnit.SECONDS) + .retryOnConnectionFailure(true) + .build(); + } + + @Override + public void init(ConnectorContext connectorContext) { + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (WeChatSinkConfig) sinkConnectorContext.getSinkConfig(); + okHttpClient = new OkHttpClient.Builder() + .connectTimeout(60, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS) + .writeTimeout(60, TimeUnit.SECONDS) + .retryOnConnectionFailure(true) + .build(); + } + + @Override + public void start() { + isRunning = true; + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getSinkConnectorConfig().getConnectorName(); + } + + @Override + public void stop() throws IOException { + isRunning = false; + } + + public boolean isRunning() { + return isRunning; + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord record : sinkRecords) { + try { + if (Objects.isNull(record.getData())) { + log.warn("ConnectRecord data is null, ignore."); + continue; + } + sendMessage(record); + } catch (Exception e) { + log.error("Failed to sink message to WeChat.", e); + } + } + } + + @SneakyThrows + private void sendMessage(ConnectRecord record) { + // get access token + String accessToken = getAccessToken(); + MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); + RequestBody body = RequestBody.create(mediaType, new String((byte[]) record.getData())); + Request request = new Request.Builder() + .url(String.format(MESSAGE_SEND_URL, accessToken)) + .post(body) + .build(); + try (Response response = okHttpClient.newCall(request).execute()) { + if (!response.isSuccessful()) { + log.error("server response: {}", ToStringBuilder.reflectionToString(response)); + throw new IOException("Unexpected code " + response); + } + + ResponseBody responseBody = response.body(); + if (responseBody == null) { + throw new IOException("Response body is null."); + } + + String jsonStr = responseBody.string(); + TemplateMessageResponse messageResponse = JsonUtils.parseObject(jsonStr, TemplateMessageResponse.class); + if (messageResponse == null) { + throw new IOException("message response is null."); + } + + if (messageResponse.getErrcode() != 0) { + throw new IllegalAccessException(String.format("Send message to WeChat error! errorCode=%s, errorMessage=%s", + messageResponse.getErrcode(), messageResponse.getErrmsg())); + } + } + + } + + @SneakyThrows + private String getAccessToken() { + return ACCESS_TOKEN_CACHE.get(ACCESS_TOKEN_CACHE_KEY, + () -> { + Request tokenRequest = new Request.Builder() + .url(String.format(ACCESS_TOKEN_URL, sinkConfig.getSinkConnectorConfig().getAppId(), + sinkConfig.getSinkConnectorConfig().getAppSecret())) + .get() + .build(); + String accessToken; + try (Response response = okHttpClient.newCall(tokenRequest).execute()) { + if (!response.isSuccessful()) { + log.error("server response: {}", ToStringBuilder.reflectionToString(response)); + throw new IOException("Unexpected code " + response); + } + + String json = Objects.requireNonNull(response.body()).string(); + JSONObject jsonObject = JSON.parseObject(json); + accessToken = Objects.requireNonNull(jsonObject).getString(ACCESS_TOKEN_CACHE_KEY); + ACCESS_TOKEN_CACHE.put(ACCESS_TOKEN_CACHE_KEY, accessToken); + } + + return accessToken; + }); + } +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-wechat/src/main/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/main/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-wechat/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..6f8face365 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-WECHAT + idc: FT + env: PRD + group: weChatSink + appId: 5034 + userName: weChatSinkUser + passWord: weChatPassWord +sinkConnectorConfig: + connectorName: weChatSink + appId: weChatAppId + appSecret: weChatAppSecret diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/test/java/org/apache/eventmesh/connector/wechat/sink/connector/WeChatSinkConnectorTest.java b/eventmesh-connectors/eventmesh-connector-wechat/src/test/java/org/apache/eventmesh/connector/wechat/sink/connector/WeChatSinkConnectorTest.java new file mode 100644 index 0000000000..d993468c18 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/test/java/org/apache/eventmesh/connector/wechat/sink/connector/WeChatSinkConnectorTest.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.connector.wechat.sink.connector; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.apache.eventmesh.connector.wechat.sink.config.WeChatSinkConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ReflectionSupport; +import org.mockito.ArgumentMatcher; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import okhttp3.Call; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; + +@ExtendWith(MockitoExtension.class) +public class WeChatSinkConnectorTest { + + private WeChatSinkConnector weChatSinkConnector; + + @Mock + private OkHttpClient okHttpClient; + + @BeforeEach + public void setUp() throws Exception { + Request tokenRequest = new Request.Builder().url("https://api.weixin.qq.com/cgi-bin/token").build(); + String tokenResponseJson = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; + ResponseBody responseBody = ResponseBody.create(MediaType.parse("application/json; charset=utf-8"), tokenResponseJson); + Response tokenResponse = new Response.Builder() + .request(tokenRequest) + .protocol(Protocol.HTTP_1_0) + .message("ok") + .code(200) + .body(responseBody) + .build(); + ArgumentMatcher tokenMatcher = (anyRequest) -> tokenRequest.url().encodedPath().startsWith(anyRequest.url().encodedPath()); + Call tokenCall = Mockito.mock(Call.class); + Mockito.doReturn(tokenCall).when(okHttpClient).newCall(Mockito.argThat(tokenMatcher)); + Mockito.doReturn(tokenResponse).when(tokenCall).execute(); + + weChatSinkConnector = new WeChatSinkConnector(); + WeChatSinkConfig weChatSinkConfig = (WeChatSinkConfig) ConfigUtil.parse(weChatSinkConnector.configClass()); + weChatSinkConnector.init(weChatSinkConfig); + Field clientField = ReflectionSupport.findFields(weChatSinkConnector.getClass(), + (f) -> f.getName().equals("okHttpClient"), + HierarchyTraversalMode.BOTTOM_UP).get(0); + clientField.setAccessible(true); + clientField.set(weChatSinkConnector, okHttpClient); + weChatSinkConnector.start(); + } + + @Test + public void testSendMessageToWeChat() throws Exception { + + Request sendMessageRequest = new Request.Builder().url("https://api.weixin.qq.com/cgi-bin/message/template/send").build(); + String sendMessageResponseJson = "{\"errcode\":0,\"errmsg\":\"ok\",\"msgid\":200228332}"; + ResponseBody sendMessageBody = ResponseBody.create(MediaType.parse("application/json; charset=utf-8"), sendMessageResponseJson); + Response sendMessageResponse = new Response.Builder() + .code(200) + .protocol(Protocol.HTTP_1_0) + .request(sendMessageRequest) + .body(sendMessageBody) + .message("ok") + .build(); + ArgumentMatcher sendMessageMatcher = + (anyRequest) -> sendMessageRequest.url().encodedPath().startsWith(anyRequest.url().encodedPath()); + Call sendMessageRequestCall = Mockito.mock(Call.class); + Mockito.doReturn(sendMessageRequestCall).when(okHttpClient).newCall(Mockito.argThat(sendMessageMatcher)); + Mockito.doReturn(sendMessageResponse).when(sendMessageRequestCall).execute(); + + List records = new ArrayList<>(); + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, + System.currentTimeMillis(), "Hello, EventMesh!".getBytes(StandardCharsets.UTF_8)); + records.add(connectRecord); + + weChatSinkConnector.put(records); + verify(okHttpClient, times(2)).newCall(any(Request.class)); + + WeChatSinkConnector.ACCESS_TOKEN_CACHE.invalidate(WeChatSinkConnector.ACCESS_TOKEN_CACHE_KEY); + } + + @Test + public void testSendMessageToWeChatAbnormally() throws Exception { + Request sendMessageRequest = new Request.Builder().url("https://api.weixin.qq.com/cgi-bin/message/template/send").build(); + String sendMessageResponseJson = "{\"errcode\":42001,\"errmsg\":\"access_token expired rid: 656e8793-061949b5-738cb8f4\"}"; + ResponseBody sendMessageBody = ResponseBody.create(MediaType.parse("application/json; charset=utf-8"), sendMessageResponseJson); + Response sendMessageResponse = new Response.Builder() + .code(200) + .protocol(Protocol.HTTP_1_0) + .request(sendMessageRequest) + .body(sendMessageBody) + .message("ok") + .build(); + ArgumentMatcher sendMessageMatcher = + (anyRequest) -> sendMessageRequest.url().encodedPath().startsWith(anyRequest.url().encodedPath()); + Call sendMessageRequestCall = Mockito.mock(Call.class); + Mockito.doReturn(sendMessageRequestCall).when(okHttpClient).newCall(Mockito.argThat(sendMessageMatcher)); + Mockito.doReturn(sendMessageResponse).when(sendMessageRequestCall).execute(); + + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, + System.currentTimeMillis(), "Hello, EventMesh!".getBytes(StandardCharsets.UTF_8)); + Method sendMessageMethod = WeChatSinkConnector.class.getDeclaredMethod("sendMessage", ConnectRecord.class); + sendMessageMethod.setAccessible(true); + Assertions.assertThrows(InvocationTargetException.class, () -> sendMessageMethod.invoke(weChatSinkConnector, connectRecord)); + } + + @AfterEach + public void tearDown() throws IOException { + weChatSinkConnector.stop(); + } + +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/test/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-wechat/src/test/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/test/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-wechat/src/test/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-wechat/src/test/resources/sink-config.yml new file mode 100644 index 0000000000..6f8face365 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wechat/src/test/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-WECHAT + idc: FT + env: PRD + group: weChatSink + appId: 5034 + userName: weChatSinkUser + passWord: weChatPassWord +sinkConnectorConfig: + connectorName: weChatSink + appId: weChatAppId + appSecret: weChatAppSecret diff --git a/eventmesh-connectors/eventmesh-connector-wecom/build.gradle b/eventmesh-connectors/eventmesh-connector-wecom/build.gradle new file mode 100644 index 0000000000..746a4f3722 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/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. + */ + +configurations { + implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' + implementation.exclude group: 'log4j', module: 'log4j' + testImplementation.exclude group: 'org.apache.logging.log4j', module: 'log4j-to-slf4j' +} + +dependencies { + implementation project(":eventmesh-common") + implementation project(":eventmesh-sdks:eventmesh-sdk-java") + implementation project(":eventmesh-openconnect:eventmesh-openconnect-java") + + implementation 'com.google.guava:guava' + implementation "io.netty:netty-all" + implementation 'org.apache.httpcomponents:httpclient' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-junit-jupiter" + testImplementation "org.mockito:mockito-inline" +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wecom/gradle.properties b/eventmesh-connectors/eventmesh-connector-wecom/gradle.properties new file mode 100644 index 0000000000..c91eb40394 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/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=wecom \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/config/WeComConnectServerConfig.java b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/config/WeComConnectServerConfig.java new file mode 100644 index 0000000000..1f864726bf --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/config/WeComConnectServerConfig.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.wecom.config; + +import org.apache.eventmesh.openconnect.api.config.Config; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class WeComConnectServerConfig extends Config { + + private boolean sinkEnable; +} diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/config/WeComMessageTemplateType.java b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/config/WeComMessageTemplateType.java new file mode 100644 index 0000000000..a166022731 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/config/WeComMessageTemplateType.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.connector.wecom.config; + +import java.util.Arrays; + +public enum WeComMessageTemplateType { + + PLAIN_TEXT("text", "text"), + MARKDOWN("markdown", "markdown"); + + private final String templateType; + + private final String templateKey; + + WeComMessageTemplateType(String templateType, String templateKey) { + this.templateType = templateType; + this.templateKey = templateKey; + } + + public String getTemplateType() { + return templateType; + } + + public String getTemplateKey() { + return templateKey; + } + + public static WeComMessageTemplateType of(String templateType) { + return Arrays.stream(values()) + .filter(v -> v.getTemplateType().equals(templateType)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("TemplateType: " + templateType + " not found.")); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/constants/ConnectRecordExtensionKeys.java b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/constants/ConnectRecordExtensionKeys.java new file mode 100644 index 0000000000..3c1a9dfa8b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/constants/ConnectRecordExtensionKeys.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.wecom.constants; + +/** + * Constants of record extension key. + */ +public interface ConnectRecordExtensionKeys { + + String WECOM_MESSAGE_TEMPLATE_TYPE = "wecomtemplatetype"; + +} diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/server/WeComConnectServer.java b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/server/WeComConnectServer.java new file mode 100644 index 0000000000..f9c4861684 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/server/WeComConnectServer.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.connector.wecom.server; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.connector.wecom.config.WeComConnectServerConfig; +import org.apache.eventmesh.connector.wecom.sink.connector.WeComSinkConnector; +import org.apache.eventmesh.openconnect.Application; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +public class WeComConnectServer { + + public static void main(String[] args) throws Exception { + + WeComConnectServerConfig weComConnectServerConfig = ConfigUtil.parse(WeComConnectServerConfig.class, + Constants.CONNECT_SERVER_CONFIG_FILE_NAME); + + if (weComConnectServerConfig.isSinkEnable()) { + Application application = new Application(); + application.run(WeComSinkConnector.class); + } + } +} diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/config/SinkConnectorConfig.java b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/config/SinkConnectorConfig.java new file mode 100644 index 0000000000..013d5a8bb7 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/config/SinkConnectorConfig.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.wecom.sink.config; + +import lombok.Data; + +@Data +public class SinkConnectorConfig { + + private String connectorName; + + private String robotWebhookKey; + +} diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/config/WeComSinkConfig.java b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/config/WeComSinkConfig.java new file mode 100644 index 0000000000..8af43bdbe8 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/config/WeComSinkConfig.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.wecom.sink.config; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class WeComSinkConfig extends SinkConfig { + + private SinkConnectorConfig sinkConnectorConfig; +} diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/connector/SendMessageRequest.java b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/connector/SendMessageRequest.java new file mode 100644 index 0000000000..43f1f1657a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/connector/SendMessageRequest.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.wecom.sink.connector; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class SendMessageRequest { + + @JsonProperty("msgtype") + private String messageType; + + @JsonProperty("text") + private Map textContent; + + @JsonProperty("markdown") + private Map markdownContent; +} diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/connector/SendMessageResponse.java b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/connector/SendMessageResponse.java new file mode 100644 index 0000000000..0a64f326d2 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/connector/SendMessageResponse.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.wecom.sink.connector; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Data; + +@Data +public class SendMessageResponse { + + @JsonProperty("errcode") + private int errorCode; + + @JsonProperty("errmsg") + private String errorMessage; +} diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/connector/WeComSinkConnector.java b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/connector/WeComSinkConnector.java new file mode 100644 index 0000000000..499104e11a --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/java/org/apache/eventmesh/connector/wecom/sink/connector/WeComSinkConnector.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.wecom.sink.connector; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.enums.EventMeshDataContentType; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.connector.wecom.config.WeComMessageTemplateType; +import org.apache.eventmesh.connector.wecom.constants.ConnectRecordExtensionKeys; +import org.apache.eventmesh.connector.wecom.sink.config.WeComSinkConfig; +import org.apache.eventmesh.openconnect.api.config.Config; +import org.apache.eventmesh.openconnect.api.connector.ConnectorContext; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; +import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import org.apache.http.client.methods.CloseableHttpResponse; +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.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +/** + * WeCom sink connector. + * WeCom doc: ... + */ +@Slf4j +public class WeComSinkConnector implements Sink { + + private static final String ROBOT_WEBHOOK_URL_PREFIX = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key="; + + private CloseableHttpClient httpClient; + + private WeComSinkConfig sinkConfig; + + private volatile boolean isRunning = false; + + @Override + public Class configClass() { + return WeComSinkConfig.class; + } + + @Override + public void init(Config config) { + this.sinkConfig = (WeComSinkConfig) config; + httpClient = HttpClientBuilder.create().build(); + } + + @Override + public void init(ConnectorContext connectorContext) { + SinkConnectorContext sinkConnectorContext = (SinkConnectorContext) connectorContext; + this.sinkConfig = (WeComSinkConfig) sinkConnectorContext.getSinkConfig(); + httpClient = HttpClientBuilder.create().build(); + } + + @Override + public void start() { + isRunning = true; + } + + @Override + public void commit(ConnectRecord record) { + + } + + @Override + public String name() { + return this.sinkConfig.getSinkConnectorConfig().getConnectorName(); + } + + @Override + public void stop() throws IOException { + isRunning = false; + httpClient.close(); + } + + public boolean isRunning() { + return isRunning; + } + + @Override + public void put(List sinkRecords) { + for (ConnectRecord record : sinkRecords) { + try { + if (Objects.isNull(record.getData())) { + log.warn("ConnectRecord data is null, ignore."); + continue; + } + sendMessage(record); + } catch (Exception e) { + log.error("Failed to sink message to WeCom.", e); + } + } + } + + @SneakyThrows + private void sendMessage(ConnectRecord record) { + final String target = ROBOT_WEBHOOK_URL_PREFIX + sinkConfig.getSinkConnectorConfig().getRobotWebhookKey(); + SendMessageRequest request = new SendMessageRequest(); + HttpPost httpPost = new HttpPost(target); + httpPost.addHeader("Content-Type", EventMeshDataContentType.JSON.getCode()); + WeComMessageTemplateType templateType = WeComMessageTemplateType.of( + Optional.ofNullable(record.getExtension(ConnectRecordExtensionKeys.WECOM_MESSAGE_TEMPLATE_TYPE)) + .orElse(WeComMessageTemplateType.PLAIN_TEXT.getTemplateType())); + Map contentMap = new HashMap<>(); + if (WeComMessageTemplateType.PLAIN_TEXT == templateType) { + contentMap.put("content", new String((byte[]) record.getData())); + request.setTextContent(contentMap); + } else if (WeComMessageTemplateType.MARKDOWN == templateType) { + contentMap.put("content", new String((byte[]) record.getData())); + request.setMarkdownContent(contentMap); + } + request.setMessageType(templateType.getTemplateKey()); + httpPost.setEntity(new StringEntity(Objects.requireNonNull(JsonUtils.toJSONString(request)), ContentType.APPLICATION_JSON)); + CloseableHttpResponse httpResponse = httpClient.execute(httpPost); + String resultStr = EntityUtils.toString(httpResponse.getEntity(), Constants.DEFAULT_CHARSET); + SendMessageResponse sendMessageResponse = Objects.requireNonNull(JsonUtils.parseObject(resultStr, SendMessageResponse.class)); + if (sendMessageResponse.getErrorCode() != 0) { + throw new IllegalAccessException(String.format("Send message to weCom error! errorCode=%s, errorMessage=%s", + sendMessageResponse.getErrorCode(), sendMessageResponse.getErrorMessage())); + } + } +} \ No newline at end of file diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-wecom/src/main/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/main/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-wecom/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..c21d5db0dc --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-WECOM + idc: FT + env: PRD + group: weComSink + appId: 5034 + userName: weComSinkUser + passWord: weComPassWord +sinkConnectorConfig: + connectorName: weComSink + robotWebhookKey: weComRobotWebhookKey diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/test/java/org/apache/eventmesh/connector/wecom/connector/WeComSinkConnectorTest.java b/eventmesh-connectors/eventmesh-connector-wecom/src/test/java/org/apache/eventmesh/connector/wecom/connector/WeComSinkConnectorTest.java new file mode 100644 index 0000000000..4cf9f3523b --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/test/java/org/apache/eventmesh/connector/wecom/connector/WeComSinkConnectorTest.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.connector.wecom.connector; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.connector.wecom.config.WeComMessageTemplateType; +import org.apache.eventmesh.connector.wecom.constants.ConnectRecordExtensionKeys; +import org.apache.eventmesh.connector.wecom.sink.config.WeComSinkConfig; +import org.apache.eventmesh.connector.wecom.sink.connector.SendMessageResponse; +import org.apache.eventmesh.connector.wecom.sink.connector.WeComSinkConnector; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; +import org.apache.eventmesh.openconnect.util.ConfigUtil; + +import org.apache.http.HttpEntity; +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.util.EntityUtils; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.commons.support.HierarchyTraversalMode; +import org.junit.platform.commons.support.ReflectionSupport; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class WeComSinkConnectorTest { + + private WeComSinkConnector connector; + + @Mock + private CloseableHttpClient httpClient; + + @BeforeEach + public void setUp() throws Exception { + connector = new WeComSinkConnector(); + CloseableHttpResponse mockedResponse = Mockito.mock(CloseableHttpResponse.class); + HttpEntity httpEntity = Mockito.mock(HttpEntity.class); + Mockito.doReturn(mockedResponse).when(httpClient).execute(any(HttpPost.class)); + Mockito.doReturn(httpEntity).when(mockedResponse).getEntity(); + WeComSinkConfig sinkConfig = (WeComSinkConfig) ConfigUtil.parse(connector.configClass()); + connector.init(sinkConfig); + Field httpClientField = ReflectionSupport.findFields(connector.getClass(), + (f) -> f.getName().equals("httpClient"), + HierarchyTraversalMode.BOTTOM_UP).get(0); + httpClientField.setAccessible(true); + httpClientField.set(connector, httpClient); + connector.start(); + } + + @Test + public void testSendMessageToWeCom() throws IOException { + try (MockedStatic entityUtilsMockedStatic = Mockito.mockStatic(EntityUtils.class)) { + entityUtilsMockedStatic.when(() -> EntityUtils.toString(any(HttpEntity.class), any(Charset.class))) + .thenReturn(JsonUtils.toJSONString(new SendMessageResponse())); + final int times = 3; + List records = new ArrayList<>(); + for (int i = 0; i < times; i++) { + RecordPartition partition = new RecordPartition(); + RecordOffset offset = new RecordOffset(); + ConnectRecord connectRecord = new ConnectRecord(partition, offset, + System.currentTimeMillis(), "Hello, EventMesh!".getBytes(StandardCharsets.UTF_8)); + connectRecord.addExtension(ConnectRecordExtensionKeys.WECOM_MESSAGE_TEMPLATE_TYPE, + WeComMessageTemplateType.PLAIN_TEXT.getTemplateType()); + records.add(connectRecord); + } + connector.put(records); + verify(httpClient, times(times)).execute(any(HttpPost.class)); + } + } + + @AfterEach + public void tearDown() throws IOException { + connector.stop(); + httpClient.close(); + } +} diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/test/resources/server-config.yml b/eventmesh-connectors/eventmesh-connector-wecom/src/test/resources/server-config.yml new file mode 100644 index 0000000000..20d6e6d592 --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/test/resources/server-config.yml @@ -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. +# + +sinkEnable: true diff --git a/eventmesh-connectors/eventmesh-connector-wecom/src/test/resources/sink-config.yml b/eventmesh-connectors/eventmesh-connector-wecom/src/test/resources/sink-config.yml new file mode 100644 index 0000000000..c21d5db0dc --- /dev/null +++ b/eventmesh-connectors/eventmesh-connector-wecom/src/test/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-WECOM + idc: FT + env: PRD + group: weComSink + appId: 5034 + userName: weComSinkUser + passWord: weComPassWord +sinkConnectorConfig: + connectorName: weComSink + robotWebhookKey: weComRobotWebhookKey diff --git a/eventmesh-connectors/sink-connector-rocketmq/build.gradle b/eventmesh-connectors/sink-connector-rocketmq/build.gradle deleted file mode 100644 index f72ce1a515..0000000000 --- a/eventmesh-connectors/sink-connector-rocketmq/build.gradle +++ /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. - */ - -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-openconnect:eventmesh-openconnect-java") - implementation rocketmq - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' -} diff --git a/eventmesh-connectors/sink-connector-rocketmq/gradle.properties b/eventmesh-connectors/sink-connector-rocketmq/gradle.properties deleted file mode 100644 index 89a6e46129..0000000000 --- a/eventmesh-connectors/sink-connector-rocketmq/gradle.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. -# -rocketmq_version=4.9.5 \ No newline at end of file diff --git a/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/RocketMQSinkWorker.java b/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/RocketMQSinkWorker.java deleted file mode 100644 index 611cdfa72e..0000000000 --- a/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/RocketMQSinkWorker.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.sink.connector.rocketmq; - -import org.apache.eventmesh.openconnect.Application; -import org.apache.eventmesh.sink.connector.rocketmq.connector.RocketMQSinkConnector; - -public class RocketMQSinkWorker { - - public static void main(String[] args) throws Exception { - - Application.run(RocketMQSinkConnector.class); - - } -} diff --git a/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/config/ConnectorConfig.java b/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/config/ConnectorConfig.java deleted file mode 100644 index 47dcd683bb..0000000000 --- a/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/config/ConnectorConfig.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.sink.connector.rocketmq.config; - -import lombok.Data; - -@Data -public class ConnectorConfig { - - private String connectorName; - - private String nameServer; - - private String topic; -} diff --git a/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/connector/RocketMQSinkConnector.java b/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/connector/RocketMQSinkConnector.java deleted file mode 100644 index c50c3969c1..0000000000 --- a/eventmesh-connectors/sink-connector-rocketmq/src/main/java/org/apache/eventmesh/sink/connector/rocketmq/connector/RocketMQSinkConnector.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.sink.connector.rocketmq.connector; - -import org.apache.eventmesh.openconnect.api.config.Config; -import org.apache.eventmesh.openconnect.api.data.ConnectRecord; -import org.apache.eventmesh.openconnect.api.sink.Sink; -import org.apache.eventmesh.sink.connector.rocketmq.config.RocketMQSinkConfig; - -import org.apache.rocketmq.client.producer.DefaultMQProducer; -import org.apache.rocketmq.client.producer.SendResult; -import org.apache.rocketmq.common.message.Message; -import org.apache.rocketmq.common.message.MessageAccessor; - -import java.util.List; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class RocketMQSinkConnector implements Sink { - - private RocketMQSinkConfig sinkConfig; - - private final DefaultMQProducer producer = new DefaultMQProducer(); - - @Override - public Class configClass() { - return RocketMQSinkConfig.class; - } - - @Override - public void init(Config config) throws Exception { - // init config for rocketmq source connector - this.sinkConfig = (RocketMQSinkConfig) config; - producer.setProducerGroup(sinkConfig.getPubSubConfig().getGroup()); - producer.setNamesrvAddr(sinkConfig.getConnectorConfig().getNameServer()); - } - - @Override - public void start() throws Exception { - producer.start(); - } - - @Override - public void commit(ConnectRecord record) { - - } - - @Override - public String name() { - return this.sinkConfig.getConnectorConfig().getConnectorName(); - } - - @Override - public void stop() { - producer.shutdown(); - } - - @Override - public void put(List sinkRecords) { - for (ConnectRecord connectRecord : sinkRecords) { - Message message = convertRecordToMessage(connectRecord); - try { - SendResult sendResult = producer.send(message); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public Message convertRecordToMessage(ConnectRecord connectRecord) { - Message message = new Message(); - message.setTopic(this.sinkConfig.getConnectorConfig().getTopic()); - message.setBody((byte[]) connectRecord.getData()); - for (String key : connectRecord.getExtensions().keySet()) { - MessageAccessor.putProperty(message, key, connectRecord.getExtension(key)); - } - return message; - } -} diff --git a/eventmesh-connectors/sink-connector-rocketmq/src/main/resources/config.yml b/eventmesh-connectors/sink-connector-rocketmq/src/main/resources/config.yml deleted file mode 100644 index cbc2aef193..0000000000 --- a/eventmesh-connectors/sink-connector-rocketmq/src/main/resources/config.yml +++ /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. -# - -pubSubConfig: - meshAddress: 127.0.0.1:10002 - subject: TopicTest - idc: FT - env: PRD - group: rocketmqSink - appId: 5031 - userName: rocketmqSinkUser - passWord: rocketmqPassWord -connectorConfig: - connectorName: rocketmqSink - nameServer: 127.0.0.1:9876 - topic: TopicTest diff --git a/eventmesh-connectors/source-connector-rocketmq/build.gradle b/eventmesh-connectors/source-connector-rocketmq/build.gradle deleted file mode 100644 index f72ce1a515..0000000000 --- a/eventmesh-connectors/source-connector-rocketmq/build.gradle +++ /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. - */ - -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-openconnect:eventmesh-openconnect-java") - implementation rocketmq - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' -} diff --git a/eventmesh-connectors/source-connector-rocketmq/gradle.properties b/eventmesh-connectors/source-connector-rocketmq/gradle.properties deleted file mode 100644 index 89a6e46129..0000000000 --- a/eventmesh-connectors/source-connector-rocketmq/gradle.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. -# -rocketmq_version=4.9.5 \ No newline at end of file diff --git a/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/RocketMQSourceWorker.java b/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/RocketMQSourceWorker.java deleted file mode 100644 index 9adc738a00..0000000000 --- a/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/RocketMQSourceWorker.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.source.connector.rocketmq; - -import org.apache.eventmesh.openconnect.Application; -import org.apache.eventmesh.source.connector.rocketmq.connector.RocketMQSourceConnector; - -public class RocketMQSourceWorker { - - public static void main(String[] args) throws Exception { - - Application.run(RocketMQSourceConnector.class); - - } - -} diff --git a/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/config/ConnectorConfig.java b/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/config/ConnectorConfig.java deleted file mode 100644 index f139bd6eb7..0000000000 --- a/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/config/ConnectorConfig.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.eventmesh.source.connector.rocketmq.config; - -import lombok.Data; - -@Data -public class ConnectorConfig { - - private String connectorName; - - private String nameserver; - - private String topic; -} diff --git a/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/connector/RocketMQSourceConnector.java b/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/connector/RocketMQSourceConnector.java deleted file mode 100644 index 190d18189d..0000000000 --- a/eventmesh-connectors/source-connector-rocketmq/src/main/java/org/apache/eventmesh/source/connector/rocketmq/connector/RocketMQSourceConnector.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.source.connector.rocketmq.connector; - -import org.apache.eventmesh.openconnect.api.config.Config; -import org.apache.eventmesh.openconnect.api.data.ConnectRecord; -import org.apache.eventmesh.openconnect.api.data.RecordOffset; -import org.apache.eventmesh.openconnect.api.data.RecordPartition; -import org.apache.eventmesh.openconnect.api.source.Source; -import org.apache.eventmesh.source.connector.rocketmq.config.RocketMQSourceConfig; - -import org.apache.rocketmq.client.consumer.DefaultLitePullConsumer; -import org.apache.rocketmq.common.message.MessageExt; - -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class RocketMQSourceConnector implements Source { - - private RocketMQSourceConfig sourceConfig; - - private final DefaultLitePullConsumer consumer = new DefaultLitePullConsumer(); - - @Override - public Class configClass() { - return RocketMQSourceConfig.class; - } - - @Override - public void init(Config config) throws Exception { - // init config for rocketmq source connector - this.sourceConfig = (RocketMQSourceConfig) config; - consumer.setConsumerGroup(sourceConfig.getPubSubConfig().getGroup()); - consumer.setNamesrvAddr(sourceConfig.getConnectorConfig().getNameserver()); - } - - @Override - public void start() throws Exception { - consumer.subscribe(sourceConfig.getConnectorConfig().getTopic(), "*"); - consumer.start(); - } - - @Override - public void commit(ConnectRecord record) { - - } - - @Override - public String name() { - return this.sourceConfig.getConnectorConfig().getConnectorName(); - } - - @Override - public void stop() { - consumer.unsubscribe(sourceConfig.getConnectorConfig().getTopic()); - consumer.shutdown(); - } - - @Override - public List poll() { - List messageExts = consumer.poll(); - List connectRecords = new ArrayList<>(messageExts.size()); - System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), messageExts); - for (MessageExt messageExt : messageExts) { - Long timestamp = System.currentTimeMillis(); - byte[] body = messageExt.getBody(); - String bodyStr = new String(body, StandardCharsets.UTF_8); - RecordPartition recordPartition = convertToRecordPartition(messageExt.getTopic(), - messageExt.getBrokerName(), messageExt.getQueueId()); - RecordOffset recordOffset = convertToRecordOffset(messageExt.getQueueOffset()); - ConnectRecord connectRecord = new ConnectRecord(recordPartition, recordOffset, timestamp, bodyStr); - connectRecord.addExtension("topic", messageExt.getTopic()); - connectRecords.add(connectRecord); - } - return connectRecords; - } - - public static RecordOffset convertToRecordOffset(Long offset) { - Map offsetMap = new HashMap<>(); - offsetMap.put("queueOffset", offset + ""); - return new RecordOffset(offsetMap); - } - - public static RecordPartition convertToRecordPartition(String topic, String brokerName, int queueId) { - Map map = new HashMap<>(); - map.put("topic", topic); - map.put("brokerName", brokerName); - map.put("queueId", queueId + ""); - return new RecordPartition(map); - } -} diff --git a/eventmesh-connectors/source-connector-rocketmq/src/main/resources/config.yml b/eventmesh-connectors/source-connector-rocketmq/src/main/resources/config.yml deleted file mode 100644 index 8f9b171ac2..0000000000 --- a/eventmesh-connectors/source-connector-rocketmq/src/main/resources/config.yml +++ /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. -# - -pubSubConfig: - meshAddress: 127.0.0.1:10002 - subject: TopicTest - idc: FT - env: PRD - group: rocketmqSource - appId: 5032 - userName: rocketmqSourceUser - passWord: rocketmqPassWord -connectorConfig: - connectorName: rocketmqSource - nameserver: 127.0.0.1:9877 - topic: TopicTest diff --git a/eventmesh-examples/build.gradle b/eventmesh-examples/build.gradle index a075a79628..9ef70836bd 100644 --- a/eventmesh-examples/build.gradle +++ b/eventmesh-examples/build.gradle @@ -15,7 +15,7 @@ * limitations under the License. */ -def grpcVersion = '1.42.2' +def grpcVersion = '1.43.2' configurations { implementation.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' @@ -25,6 +25,7 @@ dependencies { implementation project(":eventmesh-sdks:eventmesh-sdk-java") implementation project(":eventmesh-common") implementation project(":eventmesh-storage-plugin:eventmesh-storage-api") + implementation project(":eventmesh-connectors:eventmesh-connector-spring") implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'io.netty:netty-all' implementation "io.cloudevents:cloudevents-core" diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/GrpcAbstractDemo.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/GrpcAbstractDemo.java index 65ff999af6..dd3fe8cb07 100644 --- a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/GrpcAbstractDemo.java +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/GrpcAbstractDemo.java @@ -17,8 +17,9 @@ package org.apache.eventmesh.grpc; +import static org.apache.eventmesh.common.Constants.CLOUD_EVENTS_PROTOCOL_NAME; + 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.ExampleConstants; @@ -53,23 +54,23 @@ protected static EventMeshGrpcClientConfig initEventMeshGrpcClientConfig(final S .build(); } - protected static CloudEvent buildCloudEvent(final Map content) { + protected static CloudEvent buildCloudEvent(final Map content, String topic) { return CloudEventBuilder.v1() .withId(UUID.randomUUID().toString()) - .withSubject(ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC) + .withSubject(topic) .withSource(URI.create("/")) .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) - .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withType(CLOUD_EVENTS_PROTOCOL_NAME) .withData(JsonUtils.toJSONString(content).getBytes(StandardCharsets.UTF_8)) .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4 * 1000)) .build(); } - protected static EventMeshMessage buildEventMeshMessage(final Map content) { + protected static EventMeshMessage buildEventMeshMessage(final Map content, String topic) { return EventMeshMessage.builder() .content(JsonUtils.toJSONString(content)) - .topic(ExampleConstants.EVENTMESH_GRPC_BROADCAT_TEST_TOPIC) + .topic(topic) .uniqueId(RandomStringUtils.generateNum(30)) .bizSeqNo(RandomStringUtils.generateNum(30)) .build() 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 index 03705c85c8..264dcc64ab 100644 --- 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 @@ -45,7 +45,8 @@ public static void main(String[] args) throws Exception { final List cloudEventList = new ArrayList<>(); for (int i = 0; i < 5; i++) { - cloudEventList.add(buildCloudEvent(content)); + cloudEventList.add(buildCloudEvent(content, + ExampleConstants.EVENTMESH_GRPC_BROADCAT_TEST_TOPIC)); } eventMeshGrpcProducer.publish(cloudEventList); ThreadUtils.sleep(10, TimeUnit.SECONDS); 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 index 309af86048..2885d5a6fd 100644 --- 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 @@ -26,7 +26,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -44,7 +43,8 @@ public static void main(String[] args) throws Exception { content.put("content", "testAsyncMessage"); for (int i = 0; i < MESSAGE_SIZE; i++) { - eventMeshGrpcProducer.publish(buildCloudEvent(content)); + eventMeshGrpcProducer.publish(buildCloudEvent(content, + ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC)); ThreadUtils.sleep(1, TimeUnit.SECONDS); } 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 index 589432f266..8e0be97bb3 100644 --- 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 @@ -27,7 +27,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -43,7 +42,8 @@ public static void main(String[] args) throws Exception { content.put("content", "testRequestReplyMessage"); for (int i = 0; i < MESSAGE_SIZE; i++) { - eventMeshGrpcProducer.requestReply(buildCloudEvent(content), EventMeshCommon.DEFAULT_TIME_OUT_MILLS); + eventMeshGrpcProducer.requestReply(buildCloudEvent(content, + ExampleConstants.EVENTMESH_GRPC_RR_TEST_TOPIC), EventMeshCommon.DEFAULT_TIME_OUT_MILLS); ThreadUtils.sleep(1, TimeUnit.SECONDS); } 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 index b4d7c489d3..76c59cf276 100644 --- 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 @@ -26,7 +26,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -43,7 +42,8 @@ public static void main(String[] args) throws Exception { content.put("content", "testAsyncMessage"); for (int i = 0; i < MESSAGE_SIZE; i++) { - eventMeshGrpcProducer.publish(buildEventMeshMessage(content)); + eventMeshGrpcProducer.publish(buildEventMeshMessage(content, + ExampleConstants.EVENTMESH_GRPC_BROADCAT_TEST_TOPIC)); ThreadUtils.sleep(1, TimeUnit.SECONDS); } ThreadUtils.sleep(30, TimeUnit.SECONDS); 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 index 162d360ed7..56f4a4561a 100644 --- 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 @@ -26,7 +26,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -43,7 +42,8 @@ public static void main(String[] args) throws Exception { content.put("content", "testAsyncMessage"); for (int i = 0; i < MESSAGE_SIZE; i++) { - buildEventMeshMessage(content); + eventMeshGrpcProducer.publish(buildEventMeshMessage(content, + ExampleConstants.EVENTMESH_GRPC_ASYNC_TEST_TOPIC)); ThreadUtils.sleep(1, TimeUnit.SECONDS); } ThreadUtils.sleep(30, TimeUnit.SECONDS); 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 index 941f72ce81..dd56b95b55 100644 --- 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 @@ -29,7 +29,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -45,7 +44,8 @@ public static void main(String[] args) throws Exception { List messageList = new ArrayList<>(); for (int i = 0; i < 5; i++) { - messageList.add(buildEventMeshMessage(content)); + messageList.add(buildEventMeshMessage(content, + ExampleConstants.EVENTMESH_GRPC_BROADCAT_TEST_TOPIC)); } eventMeshGrpcProducer.publish(messageList); 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 index 723c0637b9..b49b584d5a 100644 --- 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 @@ -27,7 +27,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -45,7 +44,8 @@ public static void main(String[] args) throws Exception { content.put("content", "testRequestReplyMessage"); for (int i = 0; i < MESSAGE_SIZE; i++) { - eventMeshGrpcProducer.requestReply(buildEventMeshMessage(content), + eventMeshGrpcProducer.requestReply(buildEventMeshMessage(content, + ExampleConstants.EVENTMESH_GRPC_RR_TEST_TOPIC), EventMeshCommon.DEFAULT_TIME_OUT_MILLS); ThreadUtils.sleep(1, TimeUnit.SECONDS); } diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/WorkflowAsyncPublishInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/WorkflowAsyncPublishInstance.java index 07a209f709..5c41ef5a2a 100644 --- a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/WorkflowAsyncPublishInstance.java +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/pub/eventmeshmessage/WorkflowAsyncPublishInstance.java @@ -24,6 +24,7 @@ import org.apache.eventmesh.common.ExampleConstants; import org.apache.eventmesh.common.protocol.workflow.protos.ExecuteRequest; import org.apache.eventmesh.common.protocol.workflow.protos.ExecuteResponse; +import org.apache.eventmesh.common.utils.LogUtil; import org.apache.eventmesh.common.utils.ThreadUtils; import org.apache.eventmesh.grpc.GrpcAbstractDemo; import org.apache.eventmesh.selector.NacosSelector; @@ -34,7 +35,6 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; - import com.alibaba.nacos.shaded.com.google.gson.Gson; import lombok.extern.slf4j.Slf4j; @@ -66,9 +66,7 @@ public static void main(String[] args) throws Exception { EventMeshWorkflowClient eventMeshWorkflowClient = new EventMeshWorkflowClient(eventMeshWorkflowClientConfig); ExecuteResponse response = eventMeshWorkflowClient.getWorkflowClient().execute(executeRequest.build()); - if (log.isInfoEnabled()) { - log.info("received response: {}", response.toString()); - } + LogUtil.info(log, "received response: {}", response::toString); ThreadUtils.sleep(1, TimeUnit.MINUTES); 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 index 32f9baf8c5..a47da58ea2 100644 --- 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 @@ -61,9 +61,7 @@ public static void main(String[] args) throws InterruptedException, IOException @Override public Optional handle(final CloudEvent msg) { - if (log.isInfoEnabled()) { - log.info("receive async msg: {}", msg); - } + log.info("receive async msg: {}", msg); return Optional.empty(); } 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 index 53e95c68dc..f28f3fbdc5 100644 --- 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 @@ -62,9 +62,7 @@ public static void main(String[] args) throws InterruptedException, IOException @Override public Optional handle(final CloudEvent msg) { - if (log.isInfoEnabled()) { - log.info("receive request-reply msg: {}", msg); - } + log.info("receive request-reply msg: {}", msg); if (msg != null) { return Optional.of(msg); 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 index b7b7206d37..0221c703b0 100644 --- 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 @@ -60,9 +60,7 @@ public static void main(String[] args) throws InterruptedException, IOException @Override public Optional handle(final EventMeshMessage msg) { - if (log.isInfoEnabled()) { - log.info("receive async msg: {}", msg); - } + log.info("receive async msg: {}", msg); return Optional.empty(); } 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 index 7fcb04cf18..ba4038b021 100644 --- 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 @@ -61,9 +61,7 @@ public static void main(String[] args) throws InterruptedException, IOException @Override public Optional handle(final EventMeshMessage msg) { - if (log.isInfoEnabled()) { - log.info("receive async broadcast msg: {}", msg); - } + log.info("receive async broadcast msg: {}", msg); return Optional.empty(); } 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 index 56cab10108..03722ba2a5 100644 --- 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 @@ -60,9 +60,7 @@ public static void main(String[] args) throws InterruptedException, IOException @Override public Optional handle(final EventMeshMessage msg) { - if (log.isInfoEnabled()) { - log.info("receive request-reply msg: {}", msg); - } + log.info("receive request-reply msg: {}", msg); if (msg != null) { return Optional.of(msg); } else { diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowExpressAsyncSubscribe.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowExpressAsyncSubscribe.java index 4ba90adca3..64bf1f445c 100644 --- a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowExpressAsyncSubscribe.java +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowExpressAsyncSubscribe.java @@ -80,9 +80,7 @@ public static void main(String[] args) throws Exception { @Override public Optional handle(final EventMeshMessage msg) throws Exception { - if (log.isInfoEnabled()) { - log.info("receive async msg: {}", msg); - } + log.info("receive async msg: {}", msg); if (msg == null) { log.info("async msg is null, workflow end."); return Optional.empty(); @@ -96,9 +94,7 @@ public Optional handle(final EventMeshMessage msg) throws Exce .setTaskInstanceId(taskInstanceId) .setInstanceId(workflowInstanceId).build(); final ExecuteResponse response = workflowClient.getWorkflowClient().execute(executeRequest); - if (log.isInfoEnabled()) { - log.info("receive workflow msg: {}", response.getInstanceId()); - } + log.info("receive workflow msg: {}", response.getInstanceId()); return Optional.empty(); } diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowOrderAsyncSubscribe.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowOrderAsyncSubscribe.java index 2db100392e..c2fb14d993 100644 --- a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowOrderAsyncSubscribe.java +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowOrderAsyncSubscribe.java @@ -80,9 +80,7 @@ public static void main(String[] args) throws Exception { @Override public Optional handle(final EventMeshMessage msg) throws Exception { - if (log.isInfoEnabled()) { - log.info("receive async msg: {}", msg); - } + log.info("receive async msg: {}", msg); final Map props = msg.getProp(); final String workflowInstanceId = props.get("workflowinstanceid"); @@ -92,9 +90,7 @@ public Optional handle(final EventMeshMessage msg) throws Exce .setTaskInstanceId(taskInstanceId) .setInstanceId(workflowInstanceId).build(); final ExecuteResponse response = workflowClient.getWorkflowClient().execute(executeRequest); - if (log.isInfoEnabled()) { - log.info("receive workflow msg: {}", response.getInstanceId()); - } + log.info("receive workflow msg: {}", response.getInstanceId()); return Optional.empty(); } diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowPaymentAsyncSubscribe.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowPaymentAsyncSubscribe.java index 7c7c9400f4..2bd4381a86 100644 --- a/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowPaymentAsyncSubscribe.java +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/grpc/sub/WorkflowPaymentAsyncSubscribe.java @@ -80,9 +80,7 @@ public static void main(String[] args) throws Exception { @Override public Optional handle(final EventMeshMessage msg) throws Exception { - if (log.isInfoEnabled()) { - log.info("receive async msg: {}", msg); - } + log.info("receive async msg: {}", msg); if (msg == null) { log.info("async msg is null, workflow end."); return Optional.empty(); @@ -96,9 +94,7 @@ public Optional handle(final EventMeshMessage msg) throws Exce .setTaskInstanceId(taskInstanceId) .setInstanceId(workflowInstanceId).build(); final ExecuteResponse response = workflowClient.getWorkflowClient().execute(executeRequest); - if (log.isInfoEnabled()) { - log.info("receive workflow msg: {}", response.getInstanceId()); - } + log.info("receive workflow msg: {}", response.getInstanceId()); return Optional.empty(); } 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 index 0168b4f727..9162adceda 100644 --- 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 @@ -17,11 +17,13 @@ package org.apache.eventmesh.grpc.sub.app; +import org.apache.eventmesh.connector.spring.config.EventMeshAutoConfiguration; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, EventMeshAutoConfiguration.class}) public class SpringBootDemoApplication { public static void main(String[] 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 index aa95ac4487..b3e0ad4b41 100644 --- 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 @@ -17,14 +17,9 @@ 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; @@ -35,11 +30,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -import io.cloudevents.CloudEvent; -import io.cloudevents.CloudEventData; -import io.cloudevents.core.format.EventFormat; -import io.cloudevents.core.provider.EventFormatProvider; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -52,28 +42,8 @@ public class SubController { @RequestMapping(value = "/test", method = RequestMethod.POST) public String subTest(final HttpServletRequest request) { - final String protocolType = request.getHeader(ProtocolKey.PROTOCOL_TYPE); final String content = request.getParameter("content"); - - if (log.isInfoEnabled()) { - log.info("=======receive message======= {}", content); - } - - if (StringUtils.equals(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME, protocolType)) { - final String contentType = request.getHeader(ProtocolKey.CONTENT_TYPE); - - final EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(contentType); - if (eventFormat != null) { - final CloudEvent event = eventFormat.deserialize(content.getBytes(StandardCharsets.UTF_8)); - final CloudEventData cloudEventData = event.getData(); - if (cloudEventData != null) { - final String data = new String(cloudEventData.toBytes(), StandardCharsets.UTF_8); - if (log.isInfoEnabled()) { - log.info("=======receive data======= {}", data); - } - } - } - } + log.info("=======receive message======= {}", content); subService.consumeMessage(content); 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 index 90d158397b..204f122a49 100644 --- 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 @@ -21,6 +21,7 @@ import static org.apache.eventmesh.common.ExampleConstants.IDC; import static org.apache.eventmesh.common.ExampleConstants.SERVER_PORT; import static org.apache.eventmesh.common.ExampleConstants.SUB_SYS; +import static org.apache.eventmesh.util.Utils.getURL; import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; import org.apache.eventmesh.client.grpc.consumer.EventMeshGrpcConsumer; @@ -28,10 +29,10 @@ 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.io.IOException; import java.util.Collections; import java.util.Properties; import java.util.concurrent.CountDownLatch; @@ -53,11 +54,18 @@ public class SubService implements InitializingBean { private final SubscriptionItem subscriptionItem = new SubscriptionItem(); - private final String localIp = IPUtils.getLocalAddress(); + { + try { + properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + } catch (IOException e) { + log.error("Failed to read the file.", e); + } + } + private final String localPort = properties.getProperty(SERVER_PORT); private final String eventMeshIp = properties.getProperty(ExampleConstants.EVENTMESH_IP); private final String eventMeshGrpcPort = properties.getProperty(ExampleConstants.EVENTMESH_GRPC_PORT); - private final String url = "http://" + localIp + ":" + localPort + "/sub/test"; + private final String url = getURL(localPort, "/sub/test"); // CountDownLatch size is the same as messageSize in AsyncPublishInstance.java (Publisher) private final CountDownLatch countDownLatch = new CountDownLatch(AsyncPublishInstance.MESSAGE_SIZE); @@ -82,23 +90,17 @@ public void afterPropertiesSet() throws Exception { eventMeshGrpcConsumer.subscribe(Collections.singletonList(subscriptionItem), url); - properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); - // Wait for all messaged to be consumed final Thread stopThread = new Thread(() -> { try { countDownLatch.await(); } catch (InterruptedException e) { - if (log.isWarnEnabled()) { - log.warn("exception occurred when countDownLatch.await ", e); - } + log.warn("exception occurred when countDownLatch.await ", e); + Thread.currentThread().interrupt(); } - if (log.isInfoEnabled()) { - log.info("stopThread start...."); - } + log.info("stopThread start...."); - //throw new RuntimeException(); }); stopThread.start(); @@ -106,9 +108,7 @@ public void afterPropertiesSet() throws Exception { @PreDestroy public void cleanup() { - if (log.isInfoEnabled()) { - log.info("start destory ...."); - } + log.info("start destroy...."); try { eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(subscriptionItem), url); @@ -121,21 +121,15 @@ public void cleanup() { log.error("exception occurred when close consumer ", e); } - if (log.isInfoEnabled()) { - log.info("end destory."); - } + log.info("end destroy...."); } /** * Count the message already consumed */ public void consumeMessage(final String msg) { - if (log.isInfoEnabled()) { - log.info("consume message: {}", msg); - } + log.info("consume message: {}", msg); countDownLatch.countDown(); - if (log.isInfoEnabled()) { - log.info("remaining number of messages to be consumed: {}", countDownLatch.getCount()); - } + log.info("remaining number of messages to be consumed: {}", countDownLatch.getCount()); } } diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/HttpAbstractDemo.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/HttpAbstractDemo.java index 779da9f14d..7498afa97a 100644 --- a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/HttpAbstractDemo.java +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/HttpAbstractDemo.java @@ -17,8 +17,9 @@ package org.apache.eventmesh.http.demo; +import static org.apache.eventmesh.common.Constants.CLOUD_EVENTS_PROTOCOL_NAME; + import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; -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; @@ -42,7 +43,6 @@ public class HttpAbstractDemo { - protected static EventMeshHttpClientConfig initEventMeshHttpClientConfig(final String groupName) throws IOException { final Properties properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); @@ -76,7 +76,7 @@ protected static CloudEvent buildCloudEvent(final Map content) { .withSubject(ExampleConstants.EVENTMESH_HTTP_ASYNC_TEST_TOPIC) .withSource(URI.create("/")) .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) - .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withType(CLOUD_EVENTS_PROTOCOL_NAME) .withData(JsonUtils.toJSONString(content).getBytes(StandardCharsets.UTF_8)) .withExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL, String.valueOf(4_000)) .build(); 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 index 413afe9385..e9c3056592 100644 --- 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 @@ -26,7 +26,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j 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 index ab6b1263e3..469aa24620 100644 --- 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 @@ -30,7 +30,6 @@ import java.util.Map; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j 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 index 8c30891c1b..9942e807e4 100644 --- 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 @@ -27,10 +27,8 @@ import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; - @Slf4j public class AsyncSyncRequestInstance extends HttpAbstractDemo { @@ -46,19 +44,16 @@ public static void main(String[] args) throws Exception { .uniqueId(RandomStringUtils.generateNum(30)).build(); eventMeshHttpProducer.request(eventMeshMessage, new RRCallback() { + @Override public void onSuccess(final EventMeshMessage o) { - if (log.isDebugEnabled()) { - log.debug("sendmsg: {}, return: {}, cost: {} ms", eventMeshMessage.getContent(), o.getContent(), - System.currentTimeMillis() - startTime); - } + log.debug("sendmsg: {}, return: {}, cost: {}ms", + eventMeshMessage.getContent(), o.getContent(), System.currentTimeMillis() - startTime); } @Override public void onException(Throwable e) { - if (log.isDebugEnabled()) { - log.debug("send msg failed", e); - } + log.debug("send msg failed", e); } }, 3_000); 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 index 11c3a9254b..fe600ff868 100644 --- 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 @@ -26,7 +26,6 @@ import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -48,10 +47,8 @@ public static void main(String[] args) throws Exception { .build(); final EventMeshMessage rsp = eventMeshHttpProducer.request(eventMeshMessage, 10_000); - if (log.isDebugEnabled()) { - log.debug("send msg: {}, return: {}, cost:{} ms", eventMeshMessage.getContent(), rsp.getContent(), - System.currentTimeMillis() - startTime); - } + log.debug("send msg: {}, return: {}, cost: {}ms", + eventMeshMessage.getContent(), rsp.getContent(), System.currentTimeMillis() - startTime); } catch (Exception e) { log.error("send msg failed, ", e); } diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/RemoteSubscribeInstance.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/RemoteSubscribeInstance.java new file mode 100644 index 0000000000..99837d27c4 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/http/demo/sub/RemoteSubscribeInstance.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.http.demo.sub; + +import org.apache.eventmesh.client.http.EventMeshRetObj; +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.ExampleConstants; +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.http.body.client.SubscribeRequestBody; +import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; + +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +import java.util.Collections; +import java.util.Objects; + +import io.netty.handler.codec.http.HttpMethod; + +public class RemoteSubscribeInstance { + + static final CloseableHttpClient httpClient = HttpClients.createDefault(); + + public static void main(String[] args) { + subscribeRemote(); + // unsubscribeRemote(); + } + + private static void subscribeRemote() { + SubscriptionItem subscriptionItem = new SubscriptionItem(); + subscriptionItem.setTopic(ExampleConstants.EVENTMESH_HTTP_ASYNC_TEST_TOPIC); + subscriptionItem.setMode(SubscriptionMode.CLUSTERING); + subscriptionItem.setType(SubscriptionType.ASYNC); + + final RequestParam subscribeParam = buildCommonRequestParam() + .addBody(SubscribeRequestBody.TOPIC, JsonUtils.toJSONString(Collections.singletonList(subscriptionItem))) + .addBody(SubscribeRequestBody.CONSUMERGROUP, ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .addBody(SubscribeRequestBody.URL, "http://127.0.0.1:8088/sub/test") + .addBody("remoteMesh", "http://127.0.0.1:10105/eventmesh/subscribe/local"); + + postMsg(subscribeParam); + } + + private static void unsubscribeRemote() { + final RequestParam subscribeParam = buildCommonRequestParam() + .addBody(SubscribeRequestBody.TOPIC, JsonUtils.toJSONString(Collections.singletonList(ExampleConstants.EVENTMESH_HTTP_ASYNC_TEST_TOPIC))) + .addBody(SubscribeRequestBody.CONSUMERGROUP, ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) + .addBody(SubscribeRequestBody.URL, "http://127.0.0.1:8088/sub/test"); + + postMsg(subscribeParam); + } + + private static void postMsg(RequestParam subscribeParam) { + // cluster2 ip + final String target = "http://127.0.0.1:11105/eventmesh/subscribe/remote"; + try { + final String res = HttpUtils.post(httpClient, target, subscribeParam); + final EventMeshRetObj ret = JsonUtils.parseObject(res, EventMeshRetObj.class); + if (Objects.requireNonNull(ret).getRetCode() != EventMeshRetCode.SUCCESS.getRetCode()) { + throw new EventMeshException(ret.getRetCode(), ret.getRetMsg()); + } + } catch (Exception ex) { + throw new EventMeshException(String.format("Subscribe topic error, target:%s", target), ex); + } + } + + private static RequestParam buildCommonRequestParam() { + return new RequestParam(HttpMethod.POST) + .addHeader(ProtocolKey.ClientInstanceKey.IP.getKey(), IPUtils.getLocalAddress()) + .addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) + .setTimeout(Constants.DEFAULT_HTTP_TIME_OUT); + } +} 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 index 57a4c5baf4..9b277e48b4 100644 --- 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 @@ -17,11 +17,13 @@ package org.apache.eventmesh.http.demo.sub; +import org.apache.eventmesh.connector.spring.config.EventMeshAutoConfiguration; + import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, EventMeshAutoConfiguration.class}) public class SpringBootDemoApplication { public static void main(String[] 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 index 37f6cf65bd..662a4c45e8 100644 --- 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 @@ -17,7 +17,8 @@ package org.apache.eventmesh.http.demo.sub.controller; -import org.apache.eventmesh.client.tcp.common.EventMeshCommon; +import static org.apache.eventmesh.common.Constants.CLOUD_EVENTS_PROTOCOL_NAME; + 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; @@ -54,20 +55,17 @@ public class SubController { @RequestMapping(value = "/test", method = RequestMethod.POST) public String subTest(final HttpServletRequest request) { final String content = request.getParameter("content"); - if (log.isInfoEnabled()) { - log.info("receive message: {}", content); - } - @SuppressWarnings("unchecked") final Map contentMap = JsonUtils.parseObject(content, HashMap.class); - if (StringUtils.equals(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME, contentMap.get(ProtocolKey.PROTOCOL_TYPE))) { + log.info("receive message: {}", content); + @SuppressWarnings("unchecked") + final Map contentMap = JsonUtils.parseObject(content, HashMap.class); + if (StringUtils.equals(CLOUD_EVENTS_PROTOCOL_NAME, contentMap.get(ProtocolKey.PROTOCOL_TYPE))) { final EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); if (eventFormat != null) { final CloudEvent event = eventFormat.deserialize(content.getBytes(StandardCharsets.UTF_8)); final CloudEventData eventData = event.getData(); if (eventData != null) { final String data = new String(eventData.toBytes(), StandardCharsets.UTF_8); - if (log.isInfoEnabled()) { - log.info("receive data: {}", data); - } + log.info("receive data: {}", data); } } } 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 index 88f66a8745..25ce5644af 100644 --- 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 @@ -21,6 +21,7 @@ import static org.apache.eventmesh.common.ExampleConstants.IDC; import static org.apache.eventmesh.common.ExampleConstants.SERVER_PORT; import static org.apache.eventmesh.common.ExampleConstants.SUB_SYS; +import static org.apache.eventmesh.util.Utils.getURL; import org.apache.eventmesh.client.http.conf.EventMeshHttpClientConfig; import org.apache.eventmesh.client.http.consumer.EventMeshHttpConsumer; @@ -33,6 +34,7 @@ import org.apache.eventmesh.http.demo.pub.eventmeshmessage.AsyncPublishInstance; import org.apache.eventmesh.util.Utils; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -51,28 +53,33 @@ @Component public class SubService implements InitializingBean { - private transient EventMeshHttpConsumer eventMeshHttpConsumer; + private EventMeshHttpConsumer eventMeshHttpConsumer; - private transient Properties properties; + private Properties properties; - private final transient List topicList = Lists.newArrayList( - new SubscriptionItem(ExampleConstants.EVENTMESH_HTTP_ASYNC_TEST_TOPIC, SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC) - ); - private transient String testURL; + { + try { + properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); + } catch (IOException e) { + log.error("read properties file failed", e); + } + } + + final String localPort = properties.getProperty(SERVER_PORT); + final String testURL = getURL(localPort, "/sub/test"); + + private final List topicList = Lists.newArrayList( + new SubscriptionItem(ExampleConstants.EVENTMESH_HTTP_ASYNC_TEST_TOPIC, SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC)); // CountDownLatch size is the same as messageSize in AsyncPublishInstance.java (Publisher) - private transient CountDownLatch countDownLatch = new CountDownLatch(AsyncPublishInstance.MESSAGE_SIZE); + private final CountDownLatch countDownLatch = new CountDownLatch(AsyncPublishInstance.MESSAGE_SIZE); @Override - public void afterPropertiesSet() throws Exception { - properties = Utils.readPropertiesFile(ExampleConstants.CONFIG_FILE_NAME); - 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 testURL = "http://" + localIP + ":" + localPort + "/sub/test"; - - final String eventMeshIPPort = eventmeshIP + ":" + eventmeshHttpPort; + public void afterPropertiesSet() { + final String eventMeshIP = properties.getProperty(ExampleConstants.EVENTMESH_IP); + final String eventMeshHttpPort = properties.getProperty(ExampleConstants.EVENTMESH_HTTP_PORT); + + final String eventMeshIPPort = eventMeshIP + ":" + eventMeshHttpPort; final EventMeshHttpClientConfig eventMeshClientConfig = EventMeshHttpClientConfig.builder() .liteEventMeshAddr(eventMeshIPPort) .consumerGroup(ExampleConstants.DEFAULT_EVENTMESH_TEST_CONSUMER_GROUP) @@ -92,19 +99,16 @@ public void afterPropertiesSet() throws Exception { countDownLatch.await(); } catch (InterruptedException e) { log.error("interrupted exception", e); + Thread.currentThread().interrupt(); } - if (log.isInfoEnabled()) { - log.info("stopThread start...."); - } + log.info("stopThread start...."); }); stopThread.start(); } @PreDestroy public void cleanup() { - if (log.isInfoEnabled()) { - log.info("start destory ...."); - } + log.info("start destroy...."); try { final List unSubList = new ArrayList<>(); @@ -120,21 +124,15 @@ public void cleanup() { eventMeshHttpConsumer.close(); } - if (log.isInfoEnabled()) { - log.info("end destory."); - } + log.info("end destroy...."); } /** * Count the message already consumed */ public void consumeMessage(final String msg) { - if (log.isInfoEnabled()) { - log.info("consume message: {}", msg); - } + log.info("consume message: {}", msg); countDownLatch.countDown(); - if (log.isInfoEnabled()) { - log.info("remaining number: {} of messages to be consumed", countDownLatch.getCount()); - } + log.info("remaining number: {} of messages to be consumed", countDownLatch.getCount()); } } diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/spring/SpringBootDemoApplication.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/spring/SpringBootDemoApplication.java new file mode 100644 index 0000000000..954deb070e --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/spring/SpringBootDemoApplication.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.spring; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +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/spring/pub/SpringPubController.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/spring/pub/SpringPubController.java new file mode 100644 index 0000000000..b7ea8890ee --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/spring/pub/SpringPubController.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.spring.pub; + +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.connector.spring.source.connector.SpringSourceConnector; +import org.apache.eventmesh.openconnect.api.callback.SendExcepionContext; +import org.apache.eventmesh.openconnect.api.callback.SendMessageCallback; +import org.apache.eventmesh.openconnect.api.callback.SendResult; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RestController +@RequestMapping("/spring") +public class SpringPubController { + + @Autowired + private SpringSourceConnector springSourceConnector; + + @RequestMapping("/pub") + public String publish() { + final Map content = new HashMap<>(); + content.put("content", "testSpringPublishMessage"); + springSourceConnector.send(JsonUtils.toJSONString(content), new SendMessageCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + log.info("Spring source worker send message to EventMesh success! msgId={}, topic={}", + sendResult.getMessageId(), sendResult.getTopic()); + } + + @Override + public void onException(SendExcepionContext sendExcepionContext) { + log.info("Spring source worker send message to EventMesh failed!", sendExcepionContext.getCause()); + } + }); + return "success!"; + } +} diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/spring/sub/SpringSubHandler.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/spring/sub/SpringSubHandler.java new file mode 100644 index 0000000000..0dba81acf7 --- /dev/null +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/spring/sub/SpringSubHandler.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.spring.sub; + +import org.apache.eventmesh.connector.spring.sink.EventMeshListener; + +import org.springframework.stereotype.Component; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +public class SpringSubHandler { + + @EventMeshListener + public void onMessage(String message) { + log.info("[SPRING--MESSAGE-RECEIVED], data={}", message); + } +} 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 index 5df2d71713..e66fd6afbf 100644 --- 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 @@ -17,9 +17,9 @@ package org.apache.eventmesh.tcp.common; +import static org.apache.eventmesh.common.Constants.CLOUD_EVENTS_PROTOCOL_NAME; 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.Constants; import org.apache.eventmesh.common.ExampleConstants; @@ -38,8 +38,6 @@ import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; - - import io.cloudevents.CloudEvent; import io.cloudevents.core.builder.CloudEventBuilder; @@ -51,23 +49,21 @@ public class EventMeshTestUtils { private static final String DEFAULT_TTL_MS = "30000"; - private static UserAgent getUserAgent(Integer port, String subsystem, Integer pid) { return UserAgent.builder() - .env(UtilsConstants.ENV) - .host(UtilsConstants.HOST) - .password(generateRandomString(UtilsConstants.PASSWORD_LENGTH)) - .username(UtilsConstants.USER_NAME) - .group(UtilsConstants.GROUP) - .path(UtilsConstants.PATH) - .port(port) - .subsystem(subsystem) - .pid(pid) - .version(UtilsConstants.VERSION) - .idc(UtilsConstants.IDC) - .build(); - } - + .env(UtilsConstants.ENV) + .host(UtilsConstants.HOST) + .password(generateRandomString(UtilsConstants.PASSWORD_LENGTH)) + .username(UtilsConstants.USER_NAME) + .group(UtilsConstants.GROUP) + .path(UtilsConstants.PATH) + .port(port) + .subsystem(subsystem) + .pid(pid) + .version(UtilsConstants.VERSION) + .idc(UtilsConstants.IDC) + .build(); + } // generate pub-client public static UserAgent generateClient1() { @@ -109,7 +105,7 @@ public static Package rrResponse(final EventMeshMessage request) { } public static EventMeshMessage getEventMeshMessage(String eventMeshTcpSyncTestTopic, String msgType, String msg, - String keys, String keyMsg, String testMessage) { + String keys, String keyMsg, String testMessage) { final EventMeshMessage mqmsg = new EventMeshMessage(); mqmsg.setTopic(eventMeshTcpSyncTestTopic); mqmsg.getProperties().put(msgType, msg); @@ -119,28 +115,28 @@ public static EventMeshMessage getEventMeshMessage(String eventMeshTcpSyncTestTo mqmsg.setBody(testMessage); return mqmsg; } - + public static EventMeshMessage generateSyncRRMqMsg() { return getEventMeshMessage(ExampleConstants.EVENTMESH_TCP_SYNC_TEST_TOPIC, UtilsConstants.MSG_TYPE, - "persistent", UtilsConstants.KEYS, generateRandomString(16), "testSyncRR"); + "persistent", UtilsConstants.KEYS, generateRandomString(16), "testSyncRR"); } private static EventMeshMessage generateAsyncRRMqMsg() { - return getEventMeshMessage(ExampleConstants.EVENTMESH_TCP_SYNC_TEST_TOPIC, UtilsConstants.REPLY_TO, - "localhost@ProducerGroup-producerPool-9-access#V1_4_0#CI", UtilsConstants.PROPERTY_MESSAGE_REPLY_TO, - "notnull", "testAsyncRR"); + return getEventMeshMessage(ExampleConstants.EVENTMESH_TCP_SYNC_TEST_TOPIC, UtilsConstants.REPLY_TO, + "localhost@ProducerGroup-producerPool-9-access#V1_4_0#CI", UtilsConstants.PROPERTY_MESSAGE_REPLY_TO, + "notnull", "testAsyncRR"); } public static EventMeshMessage generateAsyncEventMqMsg() { return getEventMeshMessage(ExampleConstants.EVENTMESH_TCP_ASYNC_TEST_TOPIC, UtilsConstants.REPLY_TO, - "localhost@ProducerGroup-producerPool-9-access#V1_4_0#CI", UtilsConstants.PROPERTY_MESSAGE_REPLY_TO, - "notnull", ASYNC_MSG_BODY); + "localhost@ProducerGroup-producerPool-9-access#V1_4_0#CI", UtilsConstants.PROPERTY_MESSAGE_REPLY_TO, + "notnull", ASYNC_MSG_BODY); } public static EventMeshMessage generateBroadcastMqMsg() { return getEventMeshMessage(ExampleConstants.EVENTMESH_TCP_ASYNC_TEST_TOPIC, UtilsConstants.REPLY_TO, - "localhost@ProducerGroup-producerPool-9-access#V1_4_0#CI", UtilsConstants.PROPERTY_MESSAGE_REPLY_TO, - "notnull", ASYNC_MSG_BODY); + "localhost@ProducerGroup-producerPool-9-access#V1_4_0#CI", UtilsConstants.PROPERTY_MESSAGE_REPLY_TO, + "notnull", ASYNC_MSG_BODY); } private static String generateRandomString(final int length) { @@ -160,7 +156,7 @@ public static CloudEvent generateCloudEventV1Async() { .withSubject(ExampleConstants.EVENTMESH_TCP_ASYNC_TEST_TOPIC) .withSource(URI.create("/")) .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) - .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withType(CLOUD_EVENTS_PROTOCOL_NAME) .withData(Objects.requireNonNull(JsonUtils.toJSONString(content)).getBytes(StandardCharsets.UTF_8)) .withExtension(UtilsConstants.TTL, DEFAULT_TTL_MS) .build(); @@ -175,7 +171,7 @@ public static CloudEvent generateCloudEventV1SyncRR() { .withSubject(ExampleConstants.EVENTMESH_TCP_SYNC_TEST_TOPIC) .withSource(URI.create("/")) .withDataContentType(ExampleConstants.CLOUDEVENT_CONTENT_TYPE) - .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) + .withType(CLOUD_EVENTS_PROTOCOL_NAME) .withData(Objects.requireNonNull(JsonUtils.toJSONString(content)).getBytes(StandardCharsets.UTF_8)) .withExtension(UtilsConstants.TTL, DEFAULT_TTL_MS) .withExtension(UtilsConstants.MSG_TYPE, "persistent") diff --git a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/common/UtilsConstants.java b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/common/UtilsConstants.java index 4268e5f5c2..f3697d2f59 100644 --- a/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/common/UtilsConstants.java +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/tcp/common/UtilsConstants.java @@ -20,7 +20,6 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; - @NoArgsConstructor(access = AccessLevel.PRIVATE) public class UtilsConstants { @@ -48,5 +47,4 @@ public class UtilsConstants { public static final String PROPERTY_MESSAGE_REPLY_TO = "propertymessagereplyto"; public static final String CONTENT = "content"; - } 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 index f2cf36a6ee..666e2e3730 100644 --- 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 @@ -54,9 +54,7 @@ public static void main(String[] args) throws Exception { for (int i = 0; i < 2; i++) { CloudEvent event = EventMeshTestUtils.generateCloudEventV1Async(); - if (log.isInfoEnabled()) { - log.info("begin send async msg[{}]: {}", i, event); - } + log.info("begin send async msg[{}]: {}", i, event); client.publish(event, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); ThreadUtils.sleep(1, TimeUnit.SECONDS); 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 index 5967f42d4b..4be5e2569d 100644 --- 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 @@ -60,9 +60,7 @@ public static void main(String[] args) throws Exception { final CloudEvent event = EventMeshTestUtils.generateCloudEventV1SyncRR(); - if (log.isInfoEnabled()) { - log.info("begin send rr msg: {}", event); - } + log.info("begin send rr msg: {}", event); final Package response = client.rr(event, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); // check-NPE EventFormat @@ -83,9 +81,7 @@ public static void main(String[] args) throws Exception { } final String content = new String(cloudEventData.toBytes(), StandardCharsets.UTF_8); - if (log.isInfoEnabled()) { - log.info("receive rr reply: {}|{}", response, content); - } + log.info("receive rr reply: {}|{}", response, content); } catch (Exception e) { log.error("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 index 31c6f93a30..222fbb7cd9 100644 --- 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 @@ -31,7 +31,6 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -55,9 +54,7 @@ public static void main(String[] args) throws Exception { for (int i = 0; i < 5; i++) { final EventMeshMessage eventMeshMessage = EventMeshTestUtils.generateAsyncEventMqMsg(); - if (log.isInfoEnabled()) { - log.info("begin send async msg[{}]: {}", i, eventMeshMessage); - } + log.info("begin send async msg[{}]: {}", i, eventMeshMessage); client.publish(eventMeshMessage, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); ThreadUtils.sleep(1, TimeUnit.SECONDS); 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 index f60eb6a0ec..94a5a27b88 100644 --- 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 @@ -31,7 +31,6 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -54,9 +53,7 @@ public static void main(String[] args) throws Exception { final EventMeshMessage eventMeshMessage = EventMeshTestUtils.generateBroadcastMqMsg(); - if (log.isInfoEnabled()) { - log.info("begin send broadcast msg: {}", eventMeshMessage); - } + log.info("begin send broadcast msg: {}", eventMeshMessage); client.broadcast(eventMeshMessage, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); ThreadUtils.sleep(2, TimeUnit.SECONDS); 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 index d1bde38d0e..ed303e8d3e 100644 --- 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 @@ -52,14 +52,10 @@ public static void main(String[] args) throws Exception { final EventMeshMessage eventMeshMessage = EventMeshTestUtils.generateSyncRRMqMsg(); - if (log.isInfoEnabled()) { - log.info("begin send rr msg: {}", eventMeshMessage); - } + log.info("begin send rr msg: {}", eventMeshMessage); final Package response = client.rr(eventMeshMessage, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); - if (log.isInfoEnabled()) { - log.info("receive rr reply: {}", response); - } + log.info("receive rr reply: {}", response); } catch (Exception e) { log.error("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 index c9d2c71ed7..c22fafe3d1 100644 --- 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 @@ -72,9 +72,7 @@ public Optional handle(final CloudEvent msg) { } final String content = new String(msg.getData().toBytes(), StandardCharsets.UTF_8); - if (log.isInfoEnabled()) { - log.info("receive async msg: {}|{}", msg, content); - } + 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 index 854ec27df9..f6312febc0 100644 --- 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 @@ -73,9 +73,7 @@ public Optional handle(final CloudEvent event) { } final String content = new String(event.getData().toBytes(), StandardCharsets.UTF_8); - if (log.isInfoEnabled()) { - log.info("receive sync rr msg: {}|{}", event, content); - } + 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 index 7b7fb41301..3c856e9037 100644 --- 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 @@ -65,9 +65,7 @@ public static void main(String[] args) throws Exception { @Override public Optional handle(final EventMeshMessage msg) { - if (log.isInfoEnabled()) { - log.info("receive async msg: {}", 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 index f114c59e0e..411eafdeda 100644 --- 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 @@ -67,9 +67,7 @@ public static void main(String[] args) throws Exception { @Override public Optional handle(final EventMeshMessage msg) { - if (log.isInfoEnabled()) { - log.info("receive broadcast msg: {}", 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 index ccd9829ecd..93495be698 100644 --- 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 @@ -66,9 +66,7 @@ public static void main(String[] args) throws Exception { @Override public Optional handle(final EventMeshMessage msg) { - if (log.isInfoEnabled()) { - log.info("receive sync rr msg: {}", 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 index 7e0ca9699e..cca5aa23d1 100644 --- a/eventmesh-examples/src/main/java/org/apache/eventmesh/util/Utils.java +++ b/eventmesh-examples/src/main/java/org/apache/eventmesh/util/Utils.java @@ -18,6 +18,7 @@ package org.apache.eventmesh.util; import org.apache.eventmesh.common.ExampleConstants; +import org.apache.eventmesh.common.utils.IPUtils; import org.apache.commons.lang3.SystemUtils; @@ -59,12 +60,11 @@ public static boolean isWindowsOS() { private static String getLinuxLocalIp() throws SocketException { String ip = ExampleConstants.DEFAULT_EVENTMESH_IP; - for (final Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { + for (final Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { final NetworkInterface intf = en.nextElement(); final String name = intf.getName(); if (!name.contains("docker") && !name.contains("lo")) { - for (final Enumeration enumIpAddr = intf.getInetAddresses(); - enumIpAddr.hasMoreElements(); ) { + for (final Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { final InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { final String ipaddress = inetAddress.getHostAddress(); @@ -92,4 +92,13 @@ public static Properties readPropertiesFile(final String fileName) throws IOExce } } + /** + * @param port server port + * @param path path + * @return url + */ + public static String getURL(String port, String path) { + return "http://" + IPUtils.getLocalAddress() + ":" + port + path; + } + } diff --git a/eventmesh-examples/src/main/resources/application.properties b/eventmesh-examples/src/main/resources/application.properties index 962106f5cd..f53b1fb198 100644 --- a/eventmesh-examples/src/main/resources/application.properties +++ b/eventmesh-examples/src/main/resources/application.properties @@ -18,9 +18,14 @@ server.port=8088 server.name=orderapp eventmesh.ip=127.0.0.1 eventmesh.http.port=10105 -eventmesh.tcp.port=10002 +eventmesh.tcp.port=10000 eventmesh.grpc.port=10205 eventmesh.selector.type=nacos eventmesh.selector.nacos.address=127.0.0.1:8848 eventmesh.catalog.name=EVENTMESH-catalog -eventmesh.workflow.name=EVENTMESH-workflow \ No newline at end of file +eventmesh.workflow.name=EVENTMESH-workflow +eventmesh.connector.dingtalkTemplateType=text +eventmesh.connector.wecomTemplateType=text +eventmesh.connector.templateType4Lark=text +eventmesh.connector.atUsers4lark=id,name;id,name; +eventmesh.connector.atAll4Lark=false diff --git a/eventmesh-examples/src/main/resources/server-config.yml b/eventmesh-examples/src/main/resources/server-config.yml new file mode 100644 index 0000000000..5f66dd0f68 --- /dev/null +++ b/eventmesh-examples/src/main/resources/server-config.yml @@ -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. +# + +sourceEnable: true +sinkEnable: true diff --git a/eventmesh-examples/src/main/resources/sink-config.yml b/eventmesh-examples/src/main/resources/sink-config.yml new file mode 100644 index 0000000000..e49b73b984 --- /dev/null +++ b/eventmesh-examples/src/main/resources/sink-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-SPRING + idc: FT + env: PRD + group: springSink + appId: 5033 + userName: springSinkUser + passWord: springPassWord +sinkConnectorConfig: + connectorName: springSink diff --git a/eventmesh-examples/src/main/resources/source-config.yml b/eventmesh-examples/src/main/resources/source-config.yml new file mode 100644 index 0000000000..db7dd9f910 --- /dev/null +++ b/eventmesh-examples/src/main/resources/source-config.yml @@ -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. +# + +pubSubConfig: + meshAddress: 127.0.0.1:10000 + subject: TEST-TOPIC-SPRING + idc: FT + env: PRD + group: springSource + appId: 5033 + userName: springSourceUser + passWord: springPassWord +sourceConnectorConfig: + connectorName: springSource diff --git a/eventmesh-filter/build.gradle b/eventmesh-filter/build.gradle new file mode 100644 index 0000000000..ba88591b41 --- /dev/null +++ b/eventmesh-filter/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") +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/PatternEntry.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/PatternEntry.java new file mode 100644 index 0000000000..5a2493a371 --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/PatternEntry.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.filter; + +import org.apache.eventmesh.filter.condition.Condition; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; + +public class PatternEntry { + + private String patternName; + + private String patternPath; + + private final List conditionList = new ArrayList<>(); + + public PatternEntry(final String patternName, final String patternPath) { + this.patternName = patternName; + this.patternPath = patternPath; + } + + public void addCondition(Condition patternCondition) { + this.conditionList.add(patternCondition); + } + + public String getPatternName() { + return patternName; + } + + public String getPatternPath() { + return patternPath; + } + + // default filter type is OR + // todo: extend the filter type with AND + public boolean match(JsonNode jsonElement) { + for (final Condition patternCondition : conditionList) { + if (patternCondition.match(jsonElement)) { + return true; + } + } + + return false; + + } + + /** + * Returns the condition list for test only + * + * @return the condition list + */ + List getConditionList() { + return conditionList; + } +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/AnythingButCondition.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/AnythingButCondition.java new file mode 100644 index 0000000000..2d58136a70 --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/AnythingButCondition.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.filter.condition; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; + +import com.fasterxml.jackson.databind.JsonNode; + +public class AnythingButCondition implements Condition { + + private List conditionList = new ArrayList<>(); + + public AnythingButCondition(JsonNode condition) { + + if (condition.isValueNode()) { + this.conditionList.add(new SpecifiedCondition(condition)); + } + // [] + if (condition.isArray()) { + for (JsonNode element : condition) { + this.conditionList.add(new SpecifiedCondition(element)); + } + } + + // prefix,suffix + if (condition.isObject()) { + Iterator> iterator = condition.fields(); + while (iterator.hasNext()) { + Entry entry = iterator.next(); + String key = entry.getKey(); + JsonNode value = entry.getValue(); + Condition condition1 = new ConditionsBuilder().withKey(key).withParams(value).build(); + this.conditionList.add(condition1); + } + } + + } + + @Override + public boolean match(JsonNode inputEvent) { + if (inputEvent == null) { + return false; + } + + for (Condition condition : conditionList) { + if (condition.match(inputEvent)) { + return false; + } + } + return true; + } + +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/Condition.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/Condition.java new file mode 100644 index 0000000000..fbb4276c7b --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/Condition.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.filter.condition; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * + */ +public interface Condition { + + boolean match(JsonNode inputEvent); + +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/ConditionsBuilder.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/ConditionsBuilder.java new file mode 100644 index 0000000000..4e207663aa --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/ConditionsBuilder.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.filter.condition; + +import com.fasterxml.jackson.databind.JsonNode; + +public class ConditionsBuilder { + + private String key; + private JsonNode jsonNode; + + public ConditionsBuilder withKey(String key) { + this.key = key; + return this; + } + + public ConditionsBuilder withParams(JsonNode jsonNode) { + this.jsonNode = jsonNode; + return this; + } + + public Condition build() { + Condition condition = null; + switch (this.key) { + case "prefix": + condition = new PrefixCondition(this.jsonNode); + break; + case "suffix": + condition = new SuffixCondition(this.jsonNode); + break; + case "anything-but": + condition = new AnythingButCondition(this.jsonNode); + break; + case "numeric": + condition = new NumericCondition(this.jsonNode); + break; + case "exists": + condition = new ExistsCondition(this.jsonNode); + break; + case "specified": + condition = new SpecifiedCondition(this.jsonNode); + break; + default: + throw new RuntimeException("INVALID CONDITION"); + // Add cases for other keys and conditions + } + + return condition; + } +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/ExistsCondition.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/ExistsCondition.java new file mode 100644 index 0000000000..53c15bb297 --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/ExistsCondition.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.filter.condition; + +import com.fasterxml.jackson.databind.JsonNode; + +public class ExistsCondition implements Condition { + + private JsonNode exists; + + ExistsCondition(JsonNode exists) { + this.exists = exists; + } + + @Override + public boolean match(JsonNode inputEvent) { + + return this.exists.asBoolean() == (inputEvent != null); + } +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/NumericCondition.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/NumericCondition.java new file mode 100644 index 0000000000..5eb5374c7c --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/NumericCondition.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.filter.condition; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; + +public class NumericCondition implements Condition { + + List operators = new ArrayList<>(); + List nums = new ArrayList<>(); + + NumericCondition(JsonNode numeric) { + if (numeric.isArray()) { + if (numeric.size() % 2 != 0) { + throw new RuntimeException("NUMERIC NO RIGHT FORMAT"); + } + for (int i = 0; i < numeric.size(); i += 2) { + JsonNode opt = numeric.get(i); + JsonNode number = numeric.get(i + 1); + operators.add(opt.asText()); + nums.add(number.asDouble()); + } + } else { + throw new RuntimeException("NUMERIC MUST BE ARRAY"); + } + } + + private boolean compareNums(Double rule, Double target, String opt) { + int res = Double.compare(target, rule); + switch (opt) { + case "=": + return res == 0; + case "!=": + return res != 0; + case ">": + return res > 0; + case ">=": + return res >= 0; + case "<": + return res < 0; + case "<=": + return res <= 0; + default: // Never be here + return false; + } + } + + @Override + public boolean match(JsonNode inputEvent) { + if (inputEvent.isNumber()) { + for (int i = 0; i < operators.size(); ++i) { + if (!compareNums(nums.get(i), inputEvent.asDouble(), operators.get(i))) { + return false; + } + + } + + } + + return true; + } +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/PrefixCondition.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/PrefixCondition.java new file mode 100644 index 0000000000..633ed1fb02 --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/PrefixCondition.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.filter.condition; + +import com.fasterxml.jackson.databind.JsonNode; + +public class PrefixCondition implements Condition { + + private final String prefix; + + public PrefixCondition(JsonNode suffix) { + this.prefix = suffix.asText(); + } + + @Override + public boolean match(JsonNode inputEvent) { + return inputEvent.asText().startsWith(prefix); + } +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/SpecifiedCondition.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/SpecifiedCondition.java new file mode 100644 index 0000000000..f9cc3fb5db --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/SpecifiedCondition.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.filter.condition; + +import com.fasterxml.jackson.databind.JsonNode; + +public class SpecifiedCondition implements Condition { + + private final JsonNode specified; + + SpecifiedCondition(JsonNode jsonNode) { + specified = jsonNode; + } + + @Override + public boolean match(JsonNode inputEvent) { + return inputEvent.asText().equals(specified.asText()); + } +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/SuffixCondition.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/SuffixCondition.java new file mode 100644 index 0000000000..805df0ee17 --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/condition/SuffixCondition.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.filter.condition; + +import com.fasterxml.jackson.databind.JsonNode; + +public class SuffixCondition implements Condition { + + private final String suffix; + + public SuffixCondition(JsonNode suffix) { + this.suffix = suffix.asText(); + } + + @Override + public boolean match(JsonNode inputEvent) { + return inputEvent.asText().endsWith(this.suffix); + } +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/pattern/Pattern.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/pattern/Pattern.java new file mode 100644 index 0000000000..8abb306b84 --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/pattern/Pattern.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.filter.pattern; + +import org.apache.eventmesh.common.utils.JsonPathUtils; +import org.apache.eventmesh.filter.PatternEntry; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.jayway.jsonpath.PathNotFoundException; + +public class Pattern { + + private List requiredFieldList = new ArrayList<>(); + private List dataList = new ArrayList<>(); + + private String content; + + public void addRequiredFieldList(PatternEntry patternEntry) { + this.requiredFieldList.add(patternEntry); + } + + public void addDataList(PatternEntry patternEntry) { + this.dataList.add(patternEntry); + } + + public boolean filter(String content) { + this.content = content; + // this.jsonNode = JacksonUtils.STRING_TO_JSONNODE(content); + + return matchRequiredFieldList(requiredFieldList) && matchRequiredFieldList(dataList); + } + + private boolean matchRequiredFieldList(List dataList) { + + for (final PatternEntry patternEntry : dataList) { + JsonNode jsonElement = null; + try { + // content:filter + String matchRes = JsonPathUtils.matchJsonPathValue(this.content, patternEntry.getPatternPath()); + + if (StringUtils.isNoneBlank(matchRes)) { + jsonElement = JsonPathUtils.parseStrict(matchRes); + } + + if (jsonElement != null && jsonElement.isArray()) { + for (JsonNode element : jsonElement) { + if (patternEntry.match(element)) { + return true; + } + } + } else { + if (!patternEntry.match(jsonElement)) { + return false; + } + } + + } catch (PathNotFoundException | JsonProcessingException e) { + throw new RuntimeException(e); + } + + } + return true; + + } + +} diff --git a/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/patternbuild/PatternBuilder.java b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/patternbuild/PatternBuilder.java new file mode 100644 index 0000000000..5f9a71d262 --- /dev/null +++ b/eventmesh-filter/src/main/java/org/apache/eventmesh/filter/patternbuild/PatternBuilder.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.filter.patternbuild; + +import org.apache.eventmesh.common.exception.JsonException; +import org.apache.eventmesh.filter.PatternEntry; +import org.apache.eventmesh.filter.condition.Condition; +import org.apache.eventmesh.filter.condition.ConditionsBuilder; +import org.apache.eventmesh.filter.pattern.Pattern; + +import java.util.ArrayDeque; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Queue; + +import io.cloudevents.SpecVersion; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class PatternBuilder { + + private static final ObjectMapper mapper = new ObjectMapper(); + + public static Pattern build(String jsonStr) { + + Pattern pattern = new Pattern(); + JsonNode jsonNode = null; + try { + jsonNode = mapper.readTree(jsonStr); + } catch (Exception e) { + throw new JsonException("INVALID_JSON_STRING", e); + } + + if (jsonNode.isEmpty() || !jsonNode.isObject()) { + return null; + } + + // iter all json data + Iterator> iterator = jsonNode.fields(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + String key = entry.getKey(); + JsonNode value = entry.getValue(); + + if (key.equals("data")) { + + parseDataField(value, pattern); + continue; + } + + if (!value.isArray()) { + throw new JsonException("INVALID_JSON_STRING"); + } + + if (!SpecVersion.V1.getAllAttributes().contains(key)) { + throw new JsonException("INVALID_JSON_KEY"); + } + + // iter all requiredField + parseRequiredField(key, "$." + key, value, pattern); + } + + return pattern; + + } + + private static void parseDataField(JsonNode jsonNode, Pattern pattern) { + if (!jsonNode.isObject()) { + throw new JsonException("INVALID_JSON_KEY"); + } + Queue queueNode = new ArrayDeque<>(); + Node node = new Node("$.data", "data", jsonNode); + queueNode.add(node); + while (!queueNode.isEmpty()) { + Node ele = queueNode.poll(); + String elepath = ele.getPath(); + Iterator> iterator = ele.getValue().fields(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + // state + String key = entry.getKey(); + // [{"anything-but":"initializing"}] [{"anything-but":123}]} + JsonNode value = entry.getValue(); + PatternEntry patternEntry = new PatternEntry(key, elepath + "." + key); + if (!value.isObject()) { + if (value.isArray()) { + for (JsonNode node11 : value) { + // {"anything-but":"initializing"} + patternEntry.addCondition(parseCondition(node11)); + } + } + pattern.addDataList(patternEntry); + } else { + queueNode.add(new Node(elepath + "." + key, key, value)); + } + } + } + + } + + private static Condition parseCondition(JsonNode jsonNode) { + if (jsonNode.isValueNode()) { + return new ConditionsBuilder().withKey("specified").withParams(jsonNode).build(); + } + + Iterator> iterator = jsonNode.fields(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + // "anything-but" + String key = entry.getKey(); + // "initializing" + JsonNode value = entry.getValue(); + return new ConditionsBuilder().withKey(key).withParams(value).build(); + } + return null; + } + + private static void parseRequiredField(String patternName, String patternPath, JsonNode jsonNode, Pattern pattern) { + if (jsonNode.isEmpty()) { + // Empty array + throw new JsonException("INVALID_PATTERN_VALUE "); + } + PatternEntry patternEntry = new PatternEntry(patternName, patternPath); + for (final JsonNode objNode : jsonNode) { + Condition condition = parseCondition(objNode); + patternEntry.addCondition(condition); + } + + pattern.addRequiredFieldList(patternEntry); + + } + + static class Node { + + private String path; + private String key; + private JsonNode value; + + Node(String path, String key, JsonNode value) { + this.path = path; + this.key = key; + this.value = value; + } + + String getPath() { + return this.path; + } + + String getKey() { + return this.key; + } + + JsonNode getValue() { + return this.value; + } + } + +} diff --git a/eventmesh-filter/src/test/java/org/apache/eventmesh/filter/PatternTest.java b/eventmesh-filter/src/test/java/org/apache/eventmesh/filter/PatternTest.java new file mode 100644 index 0000000000..207992b0c1 --- /dev/null +++ b/eventmesh-filter/src/test/java/org/apache/eventmesh/filter/PatternTest.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. + */ + +package org.apache.eventmesh.filter; + +import org.apache.eventmesh.filter.pattern.Pattern; +import org.apache.eventmesh.filter.patternbuild.PatternBuilder; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PatternTest { + + private final String event = "{\n" + + "\"id\": \"4b26115b-73e-cf74a******\",\n" + + " \"specversion\": \"1.0\",\n" + + "\"source\": \"eventmesh.source\",\n" + + "\"type\": \"object:put\",\n" + + "\"datacontenttype\": \"application/json\",\n" + + "\"subject\": \"xxx.jpg\",\n" + + "\"time\": \"2022-01-17T12:07:48.955Z\",\n" + + "\"data\": {\n" + + "\"name\": \"test01\",\n" + + "\"state\": \"enable\",\n" + + "\"num\": 10 ,\n" + + "\"num1\": 50.7 \n" + + "}\n" + + " }"; + + @Test + public void testSpecifiedFilter() { + String condition = "{\n" + + " \"source\":[\n" + + " {\n" + + " \"prefix\":\"eventmesh.\"\n" + + " }\n" + + " ]\n" + + "}"; + Pattern pattern = PatternBuilder.build(condition); + Boolean res = pattern.filter(event); + Assertions.assertEquals(true, res); + } + + @Test + public void testPrefixFilter() { + String condition = "{\n" + + " \"source\":[\n" + + " {\n" + + " \"prefix\":\"eventmesh.\"\n" + + " }\n" + + " ]\n" + + "}"; + Pattern pattern = PatternBuilder.build(condition); + Boolean res = pattern.filter(event); + Assertions.assertEquals(true, res); + } + + @Test + public void testSuffixFilter() { + String condition = "{\n" + + " \"subject\":[\n" + + " {\n" + + " \"suffix\":\".jpg\"\n" + + " }\n" + + " ]\n" + + "}"; + Pattern pattern = PatternBuilder.build(condition); + Boolean res = pattern.filter(event); + Assertions.assertEquals(true, res); + } + + @Test + public void testNumericFilter() { + String condition = "{\n" + + " \"data\":{\n" + + " \"num\":[\n" + + " {\n" + + " \"numeric\":[\n" + + " \">\",\n" + + " 0,\n" + + " \"<=\",\n" + + " 10\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"num1\":[\n" + + " {\n" + + " \"numeric\":[\n" + + " \"=\",\n" + + " 50.7\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + Pattern pattern = PatternBuilder.build(condition); + Boolean res = pattern.filter(event); + Assertions.assertEquals(true, res); + } + + @Test + public void testExistsFilter() { + String condition = "{\n" + + " \"data\":{\n" + + " \"state\":[\n" + + " {\n" + + " \"exists\": false\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + Pattern pattern = PatternBuilder.build(condition); + Boolean res = pattern.filter(event); + Assertions.assertEquals(false, res); + } + + @Test + public void testAnythingButFilter() { + String condition = "{\n" + + " \"data\":{\n" + + " \"state\":[\n" + + " {\n" + + " \"anything-but\": \"enable\"\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + Pattern pattern = PatternBuilder.build(condition); + Boolean res = pattern.filter(event); + Assertions.assertEquals(false, res); + } + +} diff --git a/eventmesh-admin/build.gradle b/eventmesh-meta/build.gradle similarity index 100% rename from eventmesh-admin/build.gradle rename to eventmesh-meta/build.gradle diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/build.gradle b/eventmesh-meta/eventmesh-meta-api/build.gradle similarity index 100% rename from eventmesh-registry-plugin/eventmesh-registry-api/build.gradle rename to eventmesh-meta/eventmesh-meta-api/build.gradle diff --git a/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/exception/MetaException.java b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/exception/MetaException.java new file mode 100644 index 0000000000..4f29a04a73 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/exception/MetaException.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; + +/** + * MetaException + */ +public class MetaException extends RuntimeException { + + public MetaException(String message) { + super(message); + } + + public MetaException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/MetaService.java b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/MetaService.java new file mode 100644 index 0000000000..6dcf4fc132 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/MetaService.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.api.meta; + +import org.apache.eventmesh.api.exception.MetaException; +import org.apache.eventmesh.api.meta.bo.EventMeshAppSubTopicInfo; +import org.apache.eventmesh.api.meta.bo.EventMeshServicePubTopicInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * MetaService + */ +@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.META) +public interface MetaService { + + void init() throws MetaException; + + void start() throws MetaException; + + void shutdown() throws MetaException; + + List findEventMeshInfoByCluster(String clusterName) throws MetaException; + + List findAllEventMeshInfo() throws MetaException; + + default Map> findEventMeshClientDistributionData( + String clusterName, String group, String purpose) throws MetaException { + // todo find metadata + return Collections.emptyMap(); + } + + void registerMetadata(Map metadataMap); + + Map getMetaData(String key, boolean fuzzyEnabled); + + void getMetaDataWithListener(MetaServiceListener metaServiceListener, String key); + + void updateMetaData(Map metadataMap); + + void removeMetaData(String key); + + boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws MetaException; + + boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws MetaException; + + default EventMeshAppSubTopicInfo findEventMeshAppSubTopicInfoByGroup(String group) throws MetaException { + return null; + } + + default List findEventMeshServicePubTopicInfos() throws MetaException { + return Collections.emptyList(); + } +} diff --git a/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/MetaServiceListener.java b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/MetaServiceListener.java new file mode 100644 index 0000000000..b304de7801 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/MetaServiceListener.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.meta; + +/** + * MetaServiceListener + */ +public interface MetaServiceListener { + + void onChange(String key, String value); +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/bo/EventMeshAppSubTopicInfo.java b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/bo/EventMeshAppSubTopicInfo.java similarity index 97% rename from eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/bo/EventMeshAppSubTopicInfo.java rename to eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/bo/EventMeshAppSubTopicInfo.java index 2a48227570..2698e58955 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/bo/EventMeshAppSubTopicInfo.java +++ b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/bo/EventMeshAppSubTopicInfo.java @@ -15,12 +15,10 @@ * limitations under the License. */ -package org.apache.eventmesh.api.registry.bo; - +package org.apache.eventmesh.api.meta.bo; import java.util.Set; - public class EventMeshAppSubTopicInfo { String app; diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/bo/EventMeshServicePubTopicInfo.java b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/bo/EventMeshServicePubTopicInfo.java similarity index 94% rename from eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/bo/EventMeshServicePubTopicInfo.java rename to eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/bo/EventMeshServicePubTopicInfo.java index 0fccd250cd..0400f66629 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/bo/EventMeshServicePubTopicInfo.java +++ b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/bo/EventMeshServicePubTopicInfo.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.api.registry.bo; +package org.apache.eventmesh.api.meta.bo; import java.util.Set; @@ -50,8 +50,8 @@ public void setToken(String token) { } /* - * Service corresponds to an application - * */ + * Service corresponds to an application + */ @Override public String toString() { return "EventMeshServicePubTopicInfo{" diff --git a/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/config/EventMeshMetaConfig.java b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/config/EventMeshMetaConfig.java new file mode 100644 index 0000000000..d8ea8c8f81 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/config/EventMeshMetaConfig.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.meta.config; + +public class EventMeshMetaConfig { + + public static final String EVENT_MESH_PROTO = "protocol"; + +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshDataInfo.java b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/dto/EventMeshDataInfo.java similarity index 98% rename from eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshDataInfo.java rename to eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/dto/EventMeshDataInfo.java index 733345a520..e8dc7debad 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshDataInfo.java +++ b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/dto/EventMeshDataInfo.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.api.registry.dto; +package org.apache.eventmesh.api.meta.dto; import java.util.Map; diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshRegisterInfo.java b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/dto/EventMeshRegisterInfo.java similarity index 98% rename from eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshRegisterInfo.java rename to eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/dto/EventMeshRegisterInfo.java index 85b0cd4e92..898476a3dc 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshRegisterInfo.java +++ b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/dto/EventMeshRegisterInfo.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.api.registry.dto; +package org.apache.eventmesh.api.meta.dto; import java.util.Map; diff --git a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshUnRegisterInfo.java b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/dto/EventMeshUnRegisterInfo.java similarity index 97% rename from eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshUnRegisterInfo.java rename to eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/dto/EventMeshUnRegisterInfo.java index a806f3f058..79340f1949 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/dto/EventMeshUnRegisterInfo.java +++ b/eventmesh-meta/eventmesh-meta-api/src/main/java/org/apache/eventmesh/api/meta/dto/EventMeshUnRegisterInfo.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.api.registry.dto; +package org.apache.eventmesh.api.meta.dto; /** * EventMeshUnRegisterInfo diff --git a/eventmesh-meta/eventmesh-meta-consul/build.gradle b/eventmesh-meta/eventmesh-meta-consul/build.gradle new file mode 100644 index 0000000000..89a15262d1 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-consul/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 { + implementation 'com.ecwid.consul:consul-api:1.4.5' + implementation 'org.apache.httpcomponents:httpclient:4.5.13' + implementation project(":eventmesh-meta:eventmesh-meta-api") + implementation project(":eventmesh-common") + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-junit-jupiter" + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} diff --git a/eventmesh-meta/eventmesh-meta-consul/gradle.properties b/eventmesh-meta/eventmesh-meta-consul/gradle.properties new file mode 100644 index 0000000000..a4cd49e2b7 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-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=metaStorage +pluginName=consul \ No newline at end of file diff --git a/eventmesh-meta/eventmesh-meta-consul/src/main/java/org/apache/eventmesh/meta/consul/config/ConsulTLSConfig.java b/eventmesh-meta/eventmesh-meta-consul/src/main/java/org/apache/eventmesh/meta/consul/config/ConsulTLSConfig.java new file mode 100644 index 0000000000..1664a014dd --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-consul/src/main/java/org/apache/eventmesh/meta/consul/config/ConsulTLSConfig.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.meta.consul.config; + +import org.apache.eventmesh.common.config.Config; +import org.apache.eventmesh.common.config.ConfigFiled; +import org.apache.eventmesh.common.config.convert.converter.EnumConverter; + +import com.ecwid.consul.transport.TLSConfig.KeyStoreInstanceType; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@Config(prefix = "eventMesh.registry.consul.tls") +public class ConsulTLSConfig { + + @ConfigFiled(field = "keyStoreInstanceType", converter = EnumConverter.class) + private KeyStoreInstanceType keyStoreInstanceType; + + @ConfigFiled(field = "certificatePath") + private String certificatePath; + + @ConfigFiled(field = "certificatePassword") + private String certificatePassword; + + @ConfigFiled(field = "keyStorePath") + private String keyStorePath; + + @ConfigFiled(field = "keyStorePassword") + private String keyStorePassword; + +} diff --git a/eventmesh-meta/eventmesh-meta-consul/src/main/java/org/apache/eventmesh/meta/consul/service/ConsulMetaService.java b/eventmesh-meta/eventmesh-meta-consul/src/main/java/org/apache/eventmesh/meta/consul/service/ConsulMetaService.java new file mode 100644 index 0000000000..2d9b921efb --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-consul/src/main/java/org/apache/eventmesh/meta/consul/service/ConsulMetaService.java @@ -0,0 +1,215 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.meta.consul.service; + +import org.apache.eventmesh.api.exception.MetaException; +import org.apache.eventmesh.api.meta.MetaService; +import org.apache.eventmesh.api.meta.MetaServiceListener; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.config.ConfigService; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.meta.consul.config.ConsulTLSConfig; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; + +import com.ecwid.consul.transport.TLSConfig; +import com.ecwid.consul.v1.ConsulClient; +import com.ecwid.consul.v1.ConsulRawClient.Builder; +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; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ConsulMetaService implements MetaService { + + public static final String IP_PORT_SEPARATOR = ":"; + + private final AtomicBoolean initStatus = new AtomicBoolean(false); + + private final AtomicBoolean startStatus = new AtomicBoolean(false); + + private String consulHost; + + private String consulPort; + + @Getter + private ConsulClient consulClient; + + private String token; + + private ConsulTLSConfig tlsConfig; + + @Override + public void init() throws MetaException { + if (initStatus.compareAndSet(false, true)) { + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); + if (null != commonConfiguration) { + String metaStorageAddr = commonConfiguration.getMetaStorageAddr(); + if (StringUtils.isBlank(metaStorageAddr)) { + throw new MetaException("namesrvAddr cannot be null"); + } + String[] addr = metaStorageAddr.split(":"); + if (addr.length != 2) { + throw new MetaException("Illegal namesrvAddr"); + } + this.consulHost = addr[0]; + this.consulPort = addr[1]; + break; + } + } + ConsulTLSConfig tlsConfig = ConfigService.getInstance().buildConfigInstance(ConsulTLSConfig.class); + this.tlsConfig = tlsConfig; + } + } + + @Override + public void start() throws MetaException { + if (!startStatus.compareAndSet(false, true)) { + return; + } + Builder builder = Builder.builder(); + builder.setHost(consulHost); + builder.setPort(Integer.parseInt(consulPort)); + if (tlsConfig != null + && Objects.nonNull(tlsConfig.getKeyStoreInstanceType()) + && !StringUtils.isAnyBlank( + tlsConfig.getCertificatePassword(), + tlsConfig.getCertificatePath(), + tlsConfig.getKeyStorePassword(), + tlsConfig.getKeyStorePath())) { + builder.setTlsConfig(convertToTlsConfig(tlsConfig)); + } + consulClient = new ConsulClient(builder.build()); + } + + private TLSConfig convertToTlsConfig(ConsulTLSConfig tlsConfig) { + return new TLSConfig( + tlsConfig.getKeyStoreInstanceType(), + tlsConfig.getCertificatePath(), + tlsConfig.getCertificatePassword(), + tlsConfig.getKeyStorePath(), + tlsConfig.getKeyStorePassword()); + } + + @Override + public void shutdown() throws MetaException { + if (!initStatus.compareAndSet(true, false)) { + return; + } + if (!startStatus.compareAndSet(true, false)) { + return; + } + consulClient = null; + } + + @Override + public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws MetaException { + try { + String[] ipPort = eventMeshRegisterInfo.getEndPoint().split(IP_PORT_SEPARATOR); + if (ipPort == null || ipPort.length < 2) { + return false; + } + 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 MetaException(e.getMessage()); + } + log.info("EventMesh successfully registered to consul"); + return true; + } + + @Override + public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws MetaException { + try { + consulClient.agentServiceDeregister(eventMeshUnRegisterInfo.getEventMeshClusterName() + "-" + eventMeshUnRegisterInfo.getEventMeshName(), + token); + } catch (Exception e) { + throw new MetaException(e.getMessage()); + } + log.info("EventMesh successfully unregistered to consul"); + return true; + } + + // todo: to be implemented + @Override + public void getMetaDataWithListener(MetaServiceListener metaServiceListener, String key) { + + } + + @Override + public List findEventMeshInfoByCluster(String clusterName) throws MetaException { + 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 MetaException { + 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 void registerMetadata(Map metadataMap) { + + } + + @Override + public Map getMetaData(String key, boolean fuzzyEnabled) { + return null; + } + + @Override + public void updateMetaData(Map metadataMap) { + + } + + @Override + public void removeMetaData(String key) { + + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/HeatBeatScheduler.java b/eventmesh-meta/eventmesh-meta-consul/src/main/java/org/apache/eventmesh/meta/consul/service/HeatBeatScheduler.java similarity index 96% rename from eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/HeatBeatScheduler.java rename to eventmesh-meta/eventmesh-meta-consul/src/main/java/org/apache/eventmesh/meta/consul/service/HeatBeatScheduler.java index a62db12fd2..fe29a4b3ed 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/HeatBeatScheduler.java +++ b/eventmesh-meta/eventmesh-meta-consul/src/main/java/org/apache/eventmesh/meta/consul/service/HeatBeatScheduler.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.consul.service; +package org.apache.eventmesh.meta.consul.service; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; @@ -38,8 +38,7 @@ public class HeatBeatScheduler { thread.setDaemon(true); thread.setName("ConsulHeartbeatService"); return thread; - } - ); + }); public HeatBeatScheduler(ConsulClient consulClient) { this.consulClient = consulClient; @@ -91,7 +90,7 @@ public void run() { consulClient.agentCheckPass(checkId, aclToken); return; } - if (heartBeatMap.contains(instance)) { + if (heartBeatMap.containsValue(instance)) { consulClient.agentCheckPass(checkId); } } finally { diff --git a/eventmesh-meta/eventmesh-meta-consul/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService b/eventmesh-meta/eventmesh-meta-consul/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService new file mode 100644 index 0000000000..d4718366aa --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-consul/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService @@ -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.meta.consul.service.ConsulMetaService \ No newline at end of file diff --git a/eventmesh-meta/eventmesh-meta-consul/src/test/java/org/apache/eventmesh/meta/consul/service/ConsulMetaServiceTest.java b/eventmesh-meta/eventmesh-meta-consul/src/test/java/org/apache/eventmesh/meta/consul/service/ConsulMetaServiceTest.java new file mode 100644 index 0000000000..86f7448d00 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-consul/src/test/java/org/apache/eventmesh/meta/consul/service/ConsulMetaServiceTest.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.meta.consul.service; + +import static org.apache.eventmesh.common.Constants.HTTP; + +import org.apache.eventmesh.api.exception.MetaException; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.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.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class ConsulMetaServiceTest { + + @Mock + private EventMeshRegisterInfo eventMeshRegisterInfo; + @Mock + private EventMeshUnRegisterInfo eventMeshUnRegisterInfo; + + private ConsulMetaService consulMetaService; + + @BeforeEach + public void registryTest() { + consulMetaService = new ConsulMetaService(); + CommonConfiguration configuration = new CommonConfiguration(); + ConfigurationContextUtil.putIfAbsent(HTTP, configuration); + configuration.setMetaStorageAddr("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"); + } + + @AfterEach + public void after() { + consulMetaService.shutdown(); + } + + @Test + public void testInit() { + consulMetaService.init(); + consulMetaService.start(); + Assertions.assertNotNull(consulMetaService.getConsulClient()); + } + + @Test + public void testStart() { + consulMetaService.init(); + consulMetaService.start(); + Assertions.assertNotNull(consulMetaService.getConsulClient()); + } + + @Test + public void testShutdown() throws NoSuchFieldException, IllegalAccessException { + consulMetaService.init(); + consulMetaService.start(); + consulMetaService.shutdown(); + Assertions.assertNull(consulMetaService.getConsulClient()); + Class consulRegistryServiceClass = ConsulMetaService.class; + Field initStatus = consulRegistryServiceClass.getDeclaredField("initStatus"); + initStatus.setAccessible(true); + Object initStatusField = initStatus.get(consulMetaService); + + Field startStatus = consulRegistryServiceClass.getDeclaredField("startStatus"); + startStatus.setAccessible(true); + Object startStatusField = startStatus.get(consulMetaService); + + Assertions.assertFalse((Boolean.parseBoolean(initStatusField.toString()))); + Assertions.assertFalse((Boolean.parseBoolean(startStatusField.toString()))); + } + + @Test + public void testRegister() { + Assertions.assertThrows(MetaException.class, () -> { + consulMetaService.init(); + consulMetaService.start(); + consulMetaService.register(eventMeshRegisterInfo); + List eventmesh = consulMetaService.findEventMeshInfoByCluster("eventmesh"); + Assertions.assertEquals(1, eventmesh.size()); + }); + } + + @Test + public void testUnRegister() { + Assertions.assertThrows(MetaException.class, () -> { + consulMetaService.init(); + consulMetaService.start(); + consulMetaService.unRegister(eventMeshUnRegisterInfo); + List eventmesh = consulMetaService.findEventMeshInfoByCluster("eventmesh"); + Assertions.assertEquals(0, eventmesh.size()); + }); + } + + @Test + public void findEventMeshInfoByCluster() { + Assertions.assertThrows(MetaException.class, () -> { + consulMetaService.init(); + consulMetaService.start(); + consulMetaService.register(eventMeshRegisterInfo); + List eventmesh = consulMetaService.findEventMeshInfoByCluster("eventmesh"); + Assertions.assertEquals(1, eventmesh.size()); + consulMetaService.unRegister(eventMeshUnRegisterInfo); + }); + } +} diff --git a/eventmesh-meta/eventmesh-meta-etcd/build.gradle b/eventmesh-meta/eventmesh-meta-etcd/build.gradle new file mode 100644 index 0000000000..733776548b --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-etcd/build.gradle @@ -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. + */ + +dependencies { + implementation ("io.etcd:jetcd-core:0.3.0") + implementation project(":eventmesh-meta:eventmesh-meta-api") + implementation project(":eventmesh-common") + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-junit-jupiter" + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} diff --git a/eventmesh-meta/eventmesh-meta-etcd/gradle.properties b/eventmesh-meta/eventmesh-meta-etcd/gradle.properties new file mode 100644 index 0000000000..33a92eb97e --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-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=metaStorage +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-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/constant/EtcdConstant.java similarity index 95% rename from eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/constant/EtcdConstant.java rename to eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/constant/EtcdConstant.java index 16c31306d5..5c6e63ebe6 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/constant/EtcdConstant.java +++ b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/constant/EtcdConstant.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.etcd.constant; +package org.apache.eventmesh.meta.etcd.constant; /** * EtcdConstant. @@ -32,5 +32,4 @@ public class EtcdConstant { 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-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdClientFactory.java similarity index 94% rename from eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientFactory.java rename to eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdClientFactory.java index 2870cd0394..6eb7608ddc 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientFactory.java +++ b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdClientFactory.java @@ -15,11 +15,11 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.etcd.factory; +package org.apache.eventmesh.meta.etcd.factory; -import org.apache.eventmesh.api.exception.RegistryException; +import org.apache.eventmesh.api.exception.MetaException; import org.apache.eventmesh.common.Constants; -import org.apache.eventmesh.registry.etcd.constant.EtcdConstant; +import org.apache.eventmesh.meta.etcd.constant.EtcdConstant; import org.apache.commons.lang3.StringUtils; @@ -33,7 +33,6 @@ import io.etcd.jetcd.ClientBuilder; import io.etcd.jetcd.options.LeaseOption; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -41,7 +40,6 @@ public class EtcdClientFactory { 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); @@ -81,12 +79,11 @@ public static Client createClient(Properties properties) { etcdLeaseIdMap.put(serverAddr, etcdLeaseId); } catch (Throwable e) { log.error("createClient failed, address: {}", serverAddr, e); - throw new RegistryException("createClient failed", e); + throw new MetaException("createClient failed", e); } return etcdLeaseId.getClientWrapper(); } - public static void renewalLeaseId(EtcdLeaseId etcdLeaseId) { log.info("renewal of contract. server url: {}", etcdLeaseId.getUrl()); Client client = etcdLeaseId.getClientWrapper(); diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientWrapper.java b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdClientWrapper.java similarity index 97% rename from eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientWrapper.java rename to eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdClientWrapper.java index 5e0b8507b0..29019a29b1 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdClientWrapper.java +++ b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdClientWrapper.java @@ -15,8 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.etcd.factory; - +package org.apache.eventmesh.meta.etcd.factory; import io.etcd.jetcd.Auth; import io.etcd.jetcd.Client; @@ -27,7 +26,6 @@ import io.etcd.jetcd.Maintenance; import io.etcd.jetcd.Watch; - class EtcdClientWrapper implements Client { private volatile Client client; diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdLeaseId.java b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdLeaseId.java similarity index 97% rename from eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdLeaseId.java rename to eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdLeaseId.java index 28ee89f87c..a9d0055b07 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdLeaseId.java +++ b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdLeaseId.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.etcd.factory; +package org.apache.eventmesh.meta.etcd.factory; import java.util.concurrent.atomic.AtomicBoolean; @@ -85,4 +85,3 @@ 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-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdStreamObserver.java similarity index 96% rename from eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdStreamObserver.java rename to eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdStreamObserver.java index 91a4033975..fdf5827526 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/factory/EtcdStreamObserver.java +++ b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/factory/EtcdStreamObserver.java @@ -15,12 +15,11 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.etcd.factory; +package org.apache.eventmesh.meta.etcd.factory; import io.etcd.jetcd.lease.LeaseKeepAliveResponse; import io.grpc.stub.StreamObserver; - import lombok.extern.slf4j.Slf4j; @Slf4j diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/service/EtcdCustomService.java b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/service/EtcdCustomService.java similarity index 75% rename from eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/service/EtcdCustomService.java rename to eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/service/EtcdCustomService.java index 47ca18e437..11460cc684 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/service/EtcdCustomService.java +++ b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/service/EtcdCustomService.java @@ -15,14 +15,14 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.etcd.service; +package org.apache.eventmesh.meta.etcd.service; -import org.apache.eventmesh.api.exception.RegistryException; -import org.apache.eventmesh.api.registry.bo.EventMeshAppSubTopicInfo; -import org.apache.eventmesh.api.registry.bo.EventMeshServicePubTopicInfo; +import org.apache.eventmesh.api.exception.MetaException; +import org.apache.eventmesh.api.meta.bo.EventMeshAppSubTopicInfo; +import org.apache.eventmesh.api.meta.bo.EventMeshServicePubTopicInfo; import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.utils.JsonUtils; -import org.apache.eventmesh.registry.etcd.constant.EtcdConstant; +import org.apache.eventmesh.meta.etcd.constant.EtcdConstant; import org.apache.commons.collections4.CollectionUtils; @@ -40,14 +40,14 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class EtcdCustomService extends EtcdRegistryService { +public class EtcdCustomService extends EtcdMetaService { private static final String KEY_PREFIX = "eventMesh" + EtcdConstant.KEY_SEPARATOR; private static final String KEY_APP = "app"; private static final String KEY_SERVICE = "service"; @Nullable - public List findEventMeshServicePubTopicInfos() throws RegistryException { + public List findEventMeshServicePubTopicInfos() throws MetaException { Client client = getEtcdClient(); String keyPrefix = KEY_PREFIX + KEY_SERVICE + EtcdConstant.KEY_SEPARATOR; @@ -58,7 +58,6 @@ public List findEventMeshServicePubTopicInfos() th GetOption getOption = GetOption.newBuilder().withPrefix(keyByteSequence).build(); keyValues = client.getKVClient().get(keyByteSequence, getOption).get().getKvs(); - if (CollectionUtils.isNotEmpty(keyValues)) { for (KeyValue kv : keyValues) { EventMeshServicePubTopicInfo eventMeshServicePubTopicInfo = @@ -67,16 +66,19 @@ public List findEventMeshServicePubTopicInfos() th } return eventMeshServicePubTopicInfoList; } + } catch (InterruptedException e) { + log.error("[EtcdRegistryService][findEventMeshServicePubTopicInfos] InterruptedException", e); + Thread.currentThread().interrupt(); } catch (Exception e) { log.error("[EtcdRegistryService][findEventMeshServicePubTopicInfos] error", e); - throw new RegistryException(e.getMessage()); + throw new MetaException(e.getMessage()); } return Collections.emptyList(); } @Nullable - public EventMeshAppSubTopicInfo findEventMeshAppSubTopicInfoByGroup(String group) throws RegistryException { + public EventMeshAppSubTopicInfo findEventMeshAppSubTopicInfoByGroup(String group) throws MetaException { Client client = getEtcdClient(); String keyPrefix = KEY_PREFIX + KEY_APP + EtcdConstant.KEY_SEPARATOR + group; List keyValues = null; @@ -85,16 +87,16 @@ public EventMeshAppSubTopicInfo findEventMeshAppSubTopicInfoByGroup(String group GetOption getOption = GetOption.newBuilder().withPrefix(keyByteSequence).build(); keyValues = client.getKVClient().get(keyByteSequence, getOption).get().getKvs(); if (CollectionUtils.isNotEmpty(keyValues)) { - EventMeshAppSubTopicInfo eventMeshAppSubTopicInfo = - JsonUtils.parseObject( - new String(keyValues.get(0).getValue().getBytes(), Constants.DEFAULT_CHARSET), - EventMeshAppSubTopicInfo.class - ); - return eventMeshAppSubTopicInfo; + return JsonUtils.parseObject( + new String(keyValues.get(0).getValue().getBytes(), Constants.DEFAULT_CHARSET), + EventMeshAppSubTopicInfo.class); } + } catch (InterruptedException e) { + log.error("[EtcdRegistryService][findEventMeshAppSubTopicInfoByGroup] InterruptedException", e); + Thread.currentThread().interrupt(); } catch (Exception e) { log.error("[EtcdRegistryService][findEventMeshAppSubTopicInfoByGroup] error, group: {}", group, e); - throw new RegistryException(e.getMessage()); + throw new MetaException(e.getMessage()); } return null; } diff --git a/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/service/EtcdMetaService.java b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/service/EtcdMetaService.java new file mode 100644 index 0000000000..bde4e08704 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-etcd/src/main/java/org/apache/eventmesh/meta/etcd/service/EtcdMetaService.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.meta.etcd.service; + +import org.apache.eventmesh.api.exception.MetaException; +import org.apache.eventmesh.api.meta.MetaService; +import org.apache.eventmesh.api.meta.MetaServiceListener; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.Constants; +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.IPUtils; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.meta.etcd.constant.EtcdConstant; +import org.apache.eventmesh.meta.etcd.factory.EtcdClientFactory; + +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.Properties; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +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; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EtcdMetaService implements MetaService { + + private final AtomicBoolean initStatus = new AtomicBoolean(false); + + private final AtomicBoolean startStatus = 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 String instanceIp; + + private String group; + + @Getter + private Client etcdClient; + + private ConcurrentMap eventMeshRegisterInfoMap; + + private ScheduledExecutorService etcdRegistryMonitorExecutorService; + + @Override + public void init() throws MetaException { + + if (!initStatus.compareAndSet(false, true)) { + return; + } + eventMeshRegisterInfoMap = new ConcurrentHashMap<>(ConfigurationContextUtil.KEYS.size()); + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); + if (null == commonConfiguration) { + continue; + } + if (StringUtils.isBlank(commonConfiguration.getMetaStorageAddr())) { + throw new MetaException("namesrvAddr cannot be null"); + } + this.serverAddr = commonConfiguration.getMetaStorageAddr(); + this.username = commonConfiguration.getEventMeshMetaStoragePluginUsername(); + this.password = commonConfiguration.getEventMeshMetaStoragePluginPassword(); + this.instanceIp = IPUtils.getLocalAddress(); + this.group = commonConfiguration.getMeshGroup(); + break; + } + etcdRegistryMonitorExecutorService = ThreadPoolFactory.createSingleScheduledExecutor( + "EtcdRegistryMonitorThread"); + } + + @Override + public void start() throws MetaException { + + if (!startStatus.compareAndSet(false, true)) { + 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) { + log.error("[EtcdRegistryService][start] error", e); + throw new MetaException(e.getMessage()); + } + } + + @Override + public void shutdown() throws MetaException { + if (!initStatus.compareAndSet(true, false)) { + return; + } + if (!startStatus.compareAndSet(true, false)) { + return; + } + try { + if (etcdClient != null) { + etcdClient.close(); + } + if (etcdRegistryMonitorExecutorService != null && !etcdRegistryMonitorExecutorService.isShutdown()) { + etcdRegistryMonitorExecutorService.shutdown(); + } + } catch (Exception e) { + log.error("[EtcdRegistryService][shutdown] error", e); + throw new MetaException(e.getMessage()); + } + log.info("EtcdRegistryService closed"); + } + + @Override + public List findEventMeshInfoByCluster(String clusterName) throws MetaException { + List eventMeshDataInfoList = new ArrayList<>(); + + try { + String keyPrefix = clusterName == null ? KEY_PREFIX : KEY_PREFIX + EtcdConstant.KEY_SEPARATOR + clusterName; + ByteSequence keyByteSequence = ByteSequence.from(keyPrefix.getBytes(Constants.DEFAULT_CHARSET)); + 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.parseObject(new String(kv.getValue().getBytes(), Constants.DEFAULT_CHARSET), EventMeshDataInfo.class); + eventMeshDataInfoList.add(eventMeshDataInfo); + } + } + } catch (InterruptedException e) { + log.error("[EtcdRegistryService][findEventMeshInfoByCluster] InterruptedException", e); + Thread.currentThread().interrupt(); + } catch (Exception e) { + log.error("[EtcdRegistryService][findEventMeshInfoByCluster] error, clusterName: {}", clusterName, e); + throw new MetaException(e.getMessage()); + } + return eventMeshDataInfoList; + } + + @Override + public List findAllEventMeshInfo() throws MetaException { + try { + return findEventMeshInfoByCluster(null); + } catch (Exception e) { + log.error("[EtcdRegistryService][findEventMeshInfoByCluster] error", e); + throw new MetaException(e.getMessage()); + } + } + + @Override + public void registerMetadata(Map metadataMap) { + for (Map.Entry eventMeshRegisterInfo : eventMeshRegisterInfoMap.entrySet()) { + EventMeshRegisterInfo registerInfo = eventMeshRegisterInfo.getValue(); + registerInfo.setMetadata(metadataMap); + this.register(registerInfo); + } + } + + @Override + public Map getMetaData(String key, boolean fuzzyEnabled) { + return null; + } + + // todo: to be implemented + @Override + public void getMetaDataWithListener(MetaServiceListener metaServiceListener, String key) { + + } + + @Override + public void updateMetaData(Map metadataMap) { + String etcdMetaKey = instanceIp + "-" + group; + ByteSequence key = ByteSequence.from(etcdMetaKey, StandardCharsets.UTF_8); + ByteSequence value = ByteSequence.from(Objects.requireNonNull(JsonUtils.toJSONString(metadataMap)), StandardCharsets.UTF_8); + etcdClient.getKVClient().put(key, value); + } + + @Override + public void removeMetaData(String key) { + + } + + @Override + public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws MetaException { + 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(Objects.requireNonNull(JsonUtils.toJSONString(eventMeshDataInfo)) + .getBytes(Constants.DEFAULT_CHARSET)); + etcdClient.getKVClient().put(etcdKey, etcdValue, PutOption.newBuilder().withLeaseId(getLeaseId()).build()); + eventMeshRegisterInfoMap.put(eventMeshName, eventMeshRegisterInfo); + + log.info("EventMesh successfully registered to etcd, eventMeshClusterName: {}, eventMeshName: {}", + eventMeshClusterName, eventMeshName); + return true; + } catch (Exception e) { + log.error("[EtcdRegistryService][register] error, eventMeshClusterName: {}, eventMeshName: {}", + eventMeshClusterName, eventMeshName, e); + throw new MetaException(e.getMessage()); + } + } + + @Override + public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws MetaException { + String eventMeshClusterName = eventMeshUnRegisterInfo.getEventMeshClusterName(); + String eventMeshName = eventMeshUnRegisterInfo.getEventMeshName(); + try { + ByteSequence etcdKey = getEtcdKey(eventMeshClusterName, eventMeshName, + eventMeshUnRegisterInfo.getEndPoint()); + etcdClient.getKVClient().delete(etcdKey); + eventMeshRegisterInfoMap.remove(eventMeshName); + log.info("EventMesh successfully logout to etcd, eventMeshClusterName: {}, eventMeshName: {}", + eventMeshClusterName, eventMeshName); + return true; + } catch (Exception e) { + log.error("[EtcdRegistryService][unRegister] error, eventMeshClusterName: {}, eventMeshName: {}", + eventMeshClusterName, eventMeshName, e); + throw new MetaException(e.getMessage()); + } + } + + 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(Constants.DEFAULT_CHARSET)); + } + + /** + * 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 e) { + log.error("get etcdKey[{}] failed[InterruptedException]", etcdKey, e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + log.error("get etcdKey[{}] failed", etcdKey, e); + } + if (CollectionUtils.isEmpty(keyValues)) { + log.warn("eventMeshRegisterInfo [{}] is not matched in Etcd , try to register again", + eventMeshRegisterInfo.getEventMeshName()); + EtcdClientFactory.renewalLeaseId(EtcdClientFactory.getEtcdLeaseId(serverAddr)); + register(eventMeshRegisterInfo); + } + } + } + } + } +} diff --git a/eventmesh-meta/eventmesh-meta-etcd/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService b/eventmesh-meta/eventmesh-meta-etcd/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService new file mode 100644 index 0000000000..5f964d6f20 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-etcd/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService @@ -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.meta.etcd.service.EtcdMetaService \ No newline at end of file diff --git a/eventmesh-meta/eventmesh-meta-etcd/src/test/java/org/apache/eventmesh/registry/etcd/service/EtcdMetaServiceTest.java b/eventmesh-meta/eventmesh-meta-etcd/src/test/java/org/apache/eventmesh/registry/etcd/service/EtcdMetaServiceTest.java new file mode 100644 index 0000000000..5efc60d051 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-etcd/src/test/java/org/apache/eventmesh/registry/etcd/service/EtcdMetaServiceTest.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.registry.etcd.service; + +import static org.apache.eventmesh.common.Constants.HTTP; + +import org.apache.eventmesh.api.exception.MetaException; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.meta.etcd.service.EtcdMetaService; + +import java.lang.reflect.Field; +import java.util.List; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class EtcdMetaServiceTest { + + @Mock + private EventMeshRegisterInfo eventMeshRegisterInfo; + @Mock + private EventMeshUnRegisterInfo eventMeshUnRegisterInfo; + + private EtcdMetaService etcdMetaService; + + @BeforeEach + public void setUp() { + etcdMetaService = new EtcdMetaService(); + CommonConfiguration configuration = new CommonConfiguration(); + configuration.setMetaStorageAddr("127.0.0.1:2379"); + ConfigurationContextUtil.putIfAbsent(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"); + } + + @AfterEach + public void after() { + etcdMetaService.shutdown(); + } + + @Test + public void testInit() { + etcdMetaService.init(); + } + + @Test + public void testStart() { + Assertions.assertThrows(MetaException.class, () -> { + etcdMetaService.init(); + etcdMetaService.start(); + Assertions.assertNotNull(etcdMetaService); + }); + + } + + @Test + public void testShutdown() throws NoSuchFieldException, IllegalAccessException { + Assertions.assertThrows(MetaException.class, () -> { + etcdMetaService.init(); + etcdMetaService.start(); + etcdMetaService.shutdown(); + + Class etcdRegistryServiceClass = EtcdMetaService.class; + Field initStatus = etcdRegistryServiceClass.getDeclaredField("initStatus"); + initStatus.setAccessible(true); + Object initStatusField = initStatus.get(etcdMetaService); + + Field startStatus = etcdRegistryServiceClass.getDeclaredField("startStatus"); + startStatus.setAccessible(true); + Object startStatusField = startStatus.get(etcdMetaService); + }); + } + + @Test + public void testRegister() { + Assertions.assertThrows(MetaException.class, () -> { + etcdMetaService.init(); + etcdMetaService.start(); + etcdMetaService.register(eventMeshRegisterInfo); + }); + } + + @Test + public void testFindEventMeshInfo() { + Assertions.assertThrows(MetaException.class, () -> { + etcdMetaService.init(); + etcdMetaService.start(); + etcdMetaService.register(eventMeshRegisterInfo); + List eventMeshDataInfoList = etcdMetaService.findAllEventMeshInfo(); + }); + } + + @Test + public void testUnRegister() { + Assertions.assertThrows(MetaException.class, () -> { + etcdMetaService.init(); + etcdMetaService.start(); + etcdMetaService.unRegister(eventMeshUnRegisterInfo); + }); + } + +} diff --git a/eventmesh-meta/eventmesh-meta-nacos/build.gradle b/eventmesh-meta/eventmesh-meta-nacos/build.gradle new file mode 100644 index 0000000000..fe837b8084 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-nacos/build.gradle @@ -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. + */ + +dependencies { + implementation "com.alibaba.nacos:nacos-client" + implementation project(":eventmesh-meta:eventmesh-meta-api") + implementation project(":eventmesh-common") + testImplementation "org.mockito:mockito-core" + testImplementation "org.mockito:mockito-junit-jupiter" + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} diff --git a/eventmesh-meta/eventmesh-meta-nacos/gradle.properties b/eventmesh-meta/eventmesh-meta-nacos/gradle.properties new file mode 100644 index 0000000000..667be04781 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-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=metaStorage +pluginName=nacos \ No newline at end of file diff --git a/eventmesh-meta/eventmesh-meta-nacos/src/main/java/org/apache/eventmesh/meta/nacos/config/NacosMetaStorageConfiguration.java b/eventmesh-meta/eventmesh-meta-nacos/src/main/java/org/apache/eventmesh/meta/nacos/config/NacosMetaStorageConfiguration.java new file mode 100644 index 0000000000..67e51d2d9e --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-nacos/src/main/java/org/apache/eventmesh/meta/nacos/config/NacosMetaStorageConfiguration.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.meta.nacos.config; + +import org.apache.eventmesh.common.config.Config; +import org.apache.eventmesh.common.config.ConfigFiled; + +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.client.naming.utils.UtilAndComs; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@Config(prefix = "eventMesh.metaStorage.nacos") +public class NacosMetaStorageConfiguration { + + @ConfigFiled(field = PropertyKeyConst.ENDPOINT) + private String endpoint; + + @ConfigFiled(field = PropertyKeyConst.ENDPOINT_PORT) + private String endpointPort; + + @ConfigFiled(field = PropertyKeyConst.ACCESS_KEY) + private String accessKey; + + @ConfigFiled(field = PropertyKeyConst.SECRET_KEY) + private String secretKey; + + @ConfigFiled(field = PropertyKeyConst.CLUSTER_NAME) + private String clusterName; + + @ConfigFiled(field = PropertyKeyConst.NAMESPACE) + private String namespace; + + @ConfigFiled(field = PropertyKeyConst.NAMING_POLLING_THREAD_COUNT) + private Integer pollingThreadCount = Runtime.getRuntime().availableProcessors() / 2 + 1; + + @ConfigFiled(field = UtilAndComs.NACOS_NAMING_LOG_NAME) + private String logFileName; + + @ConfigFiled(field = UtilAndComs.NACOS_NAMING_LOG_LEVEL) + private String logLevel; + +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/constant/NacosConstant.java b/eventmesh-meta/eventmesh-meta-nacos/src/main/java/org/apache/eventmesh/meta/nacos/constant/NacosConstant.java similarity index 95% rename from eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/constant/NacosConstant.java rename to eventmesh-meta/eventmesh-meta-nacos/src/main/java/org/apache/eventmesh/meta/nacos/constant/NacosConstant.java index 0164dc1336..94281723a7 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/constant/NacosConstant.java +++ b/eventmesh-meta/eventmesh-meta-nacos/src/main/java/org/apache/eventmesh/meta/nacos/constant/NacosConstant.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.nacos.constant; +package org.apache.eventmesh.meta.nacos.constant; /** * NacosConstant. diff --git a/eventmesh-meta/eventmesh-meta-nacos/src/main/java/org/apache/eventmesh/meta/nacos/service/NacosMetaService.java b/eventmesh-meta/eventmesh-meta-nacos/src/main/java/org/apache/eventmesh/meta/nacos/service/NacosMetaService.java new file mode 100644 index 0000000000..ca612ae07f --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-nacos/src/main/java/org/apache/eventmesh/meta/nacos/service/NacosMetaService.java @@ -0,0 +1,421 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.meta.nacos.service; + +import org.apache.eventmesh.api.exception.MetaException; +import org.apache.eventmesh.api.meta.MetaService; +import org.apache.eventmesh.api.meta.MetaServiceListener; +import org.apache.eventmesh.api.meta.config.EventMeshMetaConfig; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.config.ConfigService; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.common.utils.IPUtils; +import org.apache.eventmesh.meta.nacos.config.NacosMetaStorageConfiguration; +import org.apache.eventmesh.meta.nacos.constant.NacosConstant; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +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.Optional; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; + +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.PropertyKeyConst; +import com.alibaba.nacos.api.config.listener.Listener; +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.utils.UtilAndComs; +import com.alibaba.nacos.common.utils.CollectionUtils; +import com.alibaba.nacos.common.utils.JacksonUtils; +import com.fasterxml.jackson.databind.JsonNode; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NacosMetaService implements MetaService { + + private final AtomicBoolean initStatus = new AtomicBoolean(false); + + private final AtomicBoolean startStatus = new AtomicBoolean(false); + + @Getter + private String serverAddr; + + @Getter + private String username; + + @Getter + private String password; + + @Getter + private NacosMetaStorageConfiguration nacosConfig; + + private String dataId; + + private String group; + + @Getter + private NamingService nacosNamingService; + + private com.alibaba.nacos.api.config.ConfigService nacosConfigService; + + private ConcurrentMap eventMeshRegisterInfoMap; + + private MetaServiceListener metaServiceListener; + + @Override + public void init() throws MetaException { + + if (!initStatus.compareAndSet(false, true)) { + return; + } + eventMeshRegisterInfoMap = new ConcurrentHashMap<>(ConfigurationContextUtil.KEYS.size()); + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); + if (null == commonConfiguration) { + continue; + } + if (StringUtils.isBlank(commonConfiguration.getMetaStorageAddr())) { + throw new MetaException("namesrvAddr cannot be null"); + } + + this.serverAddr = commonConfiguration.getMetaStorageAddr(); + this.username = commonConfiguration.getEventMeshMetaStoragePluginUsername(); + this.password = commonConfiguration.getEventMeshMetaStoragePluginPassword(); + this.dataId = IPUtils.getLocalAddress(); + this.group = commonConfiguration.getMeshGroup(); + break; + } + ConfigService configService = ConfigService.getInstance(); + NacosMetaStorageConfiguration nacosConfig = configService.buildConfigInstance(NacosMetaStorageConfiguration.class); + if (nacosConfig != null) { + this.nacosConfig = nacosConfig; + } + } + + @Override + public void start() throws MetaException { + + if (!startStatus.compareAndSet(false, true)) { + return; + } + Properties properties = buildProperties(); + // registry + try { + this.nacosNamingService = NacosFactory.createNamingService(properties); + } catch (NacosException e) { + log.error("[NacosRegistryService][start] error", e); + throw new MetaException(e.getMessage()); + } + // config + try { + this.nacosConfigService = NacosFactory.createConfigService(properties); + } catch (NacosException e) { + log.error("[NacosConfigService][start] error", e); + throw new MetaException(e.getMessage()); + } + } + + private Properties buildProperties() { + Properties properties = new Properties(); + properties.setProperty(NacosConstant.SERVER_ADDR, serverAddr); + properties.setProperty(NacosConstant.USERNAME, username); + properties.setProperty(NacosConstant.PASSWORD, password); + if (nacosConfig == null) { + return properties; + } + String endpoint = nacosConfig.getEndpoint(); + if (Objects.nonNull(endpoint) && endpoint.contains(":")) { + int index = endpoint.indexOf(":"); + properties.put(PropertyKeyConst.ENDPOINT, endpoint.substring(0, index)); + properties.put(PropertyKeyConst.ENDPOINT_PORT, endpoint.substring(index + 1)); + } else { + Optional.ofNullable(endpoint).ifPresent(value -> properties.put(PropertyKeyConst.ENDPOINT, endpoint)); + String endpointPort = nacosConfig.getEndpointPort(); + Optional.ofNullable(endpointPort).ifPresent(value -> properties.put(PropertyKeyConst.ENDPOINT_PORT, endpointPort)); + } + String accessKey = nacosConfig.getAccessKey(); + Optional.ofNullable(accessKey).ifPresent(value -> properties.put(PropertyKeyConst.ACCESS_KEY, accessKey)); + String secretKey = nacosConfig.getSecretKey(); + Optional.ofNullable(secretKey).ifPresent(value -> properties.put(PropertyKeyConst.SECRET_KEY, secretKey)); + String clusterName = nacosConfig.getClusterName(); + Optional.ofNullable(clusterName).ifPresent(value -> properties.put(PropertyKeyConst.CLUSTER_NAME, clusterName)); + String logFileName = nacosConfig.getLogFileName(); + Optional.ofNullable(logFileName).ifPresent(value -> properties.put(UtilAndComs.NACOS_NAMING_LOG_NAME, logFileName)); + String logLevel = nacosConfig.getLogLevel(); + Optional.ofNullable(logLevel).ifPresent(value -> properties.put(UtilAndComs.NACOS_NAMING_LOG_LEVEL, logLevel)); + Integer pollingThreadCount = nacosConfig.getPollingThreadCount(); + Optional.ofNullable(pollingThreadCount).ifPresent(value -> properties.put(PropertyKeyConst.NAMING_POLLING_THREAD_COUNT, pollingThreadCount)); + String namespace = nacosConfig.getNamespace(); + Optional.ofNullable(namespace).ifPresent(value -> properties.put(PropertyKeyConst.NAMESPACE, namespace)); + return properties; + } + + @Override + public void getMetaDataWithListener(MetaServiceListener metaServiceListener, String key) { + try { + nacosConfigService.addListener(key, group, new Listener() { + + @Override + public Executor getExecutor() { + return null; + } + + @Override + public void receiveConfigInfo(String configInfo) { + metaServiceListener.onChange(key, configInfo); + } + }); + } catch (Exception e) { + throw new RuntimeException("add nacos listener for key " + key + "error", e); + } + } + + @Override + public void shutdown() throws MetaException { + if (!initStatus.compareAndSet(true, false)) { + return; + } + if (!startStatus.compareAndSet(true, false)) { + return; + } + try { + nacosNamingService.shutDown(); + log.info("NacosRegistryService close"); + } catch (NacosException e) { + log.error("[NacosRegistryService][shutdown] error", e); + throw new MetaException(e.getMessage()); + } + try { + nacosConfigService.shutDown(); + log.info("NacosConfigService close"); + } catch (NacosException e) { + log.error("[NacosConfigService][shutdown] error", e); + throw new MetaException(e.getMessage()); + } + } + + @Override + public List findEventMeshInfoByCluster(String clusterName) throws MetaException { + return findEventMeshInfos(true, Collections.singletonList(clusterName)); + } + + @Override + public List findAllEventMeshInfo() throws MetaException { + return findEventMeshInfos(false, null); + } + + private List findEventMeshInfos(boolean inCluster, List clusters) { + List eventMeshDataInfoList = new ArrayList<>(); + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration configuration = ConfigurationContextUtil.get(key); + if (Objects.isNull(configuration)) { + continue; + } + String eventMeshName = configuration.getEventMeshName(); + try { + List instances = + nacosNamingService.selectInstances(eventMeshName + "-" + key, + key + "-" + (inCluster ? configuration.getEventMeshCluster() : NacosConstant.GROUP), + clusters, + 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) { + log.error("[NacosRegistryService][findEventMeshInfoByCluster] error", e); + throw new MetaException(e.getMessage()); + } + } + return eventMeshDataInfoList; + } + + @Override + public void registerMetadata(Map metadataMap) { + for (Map.Entry eventMeshRegisterInfo : eventMeshRegisterInfoMap.entrySet()) { + EventMeshRegisterInfo registerInfo = eventMeshRegisterInfo.getValue(); + registerInfo.setMetadata(metadataMap); + this.register(registerInfo); + } + } + + // implement with http + @Override + public Map getMetaData(String key, boolean fuzzyEnabled) { + if (fuzzyEnabled) { + key = key + "*"; + } + int pageNo = 1; + int pageSize = 100; + + Map result = new HashMap<>(); + Map tmpMap; + do { + tmpMap = getResultFromNacos(pageNo, pageSize, key, group, fuzzyEnabled); + result.putAll(tmpMap); + } while (!(tmpMap.size() < pageSize)); + return result; + } + + private Map getResultFromNacos(int pageNo, int pageSize, String key, String group, boolean fuzzyEnabled) { + Map result = new HashMap<>(); + try (CloseableHttpClient httpclient = HttpClients.createDefault()) { + URIBuilder uriBuilder = new URIBuilder("http://" + serverAddr + "/nacos/v1/cs/configs") + .setParameter("dataId", key) + .setParameter("group", group) + .setParameter("pageNo", String.valueOf(pageNo)) + .setParameter("pageSize", String.valueOf(pageSize)); + if (fuzzyEnabled) { + uriBuilder.setParameter("search", "blur"); + } + URI uri = uriBuilder.build(); + HttpGet httpGet = new HttpGet(uri); + httpGet.setHeader(NacosConstant.USERNAME, username); + httpGet.setHeader(NacosConstant.PASSWORD, password); + try (CloseableHttpResponse closeableHttpResponse = httpclient.execute(httpGet)) { + if (closeableHttpResponse.getStatusLine().getStatusCode() == 200) { + String response = EntityUtils.toString(closeableHttpResponse.getEntity(), StandardCharsets.UTF_8); + result = processResponse(response); + } + } catch (Exception e) { + log.error("get metaData fail", e); + throw new RuntimeException(e); + } + return result; + } catch (Exception e) { + log.error("get metaData fail", e); + throw new RuntimeException(e); + } + } + + private Map processResponse(String response) { + Map result = new HashMap<>(); + JsonNode jsonNode = JacksonUtils.toObj(response); + JsonNode jsonNodeArray = jsonNode.get("pageItems"); + if (jsonNodeArray.isArray()) { + for (JsonNode js : jsonNodeArray) { + String key = js.get("dataId").asText(); + String value = js.get("content").asText(); + result.put(key, value); + } + } + return result; + } + + @Override + public void updateMetaData(Map metadataMap) { + String protocol = metadataMap.get(EventMeshMetaConfig.EVENT_MESH_PROTO); + String nacosDataId = dataId + "-" + protocol; + try { + boolean flag = this.nacosConfigService.publishConfig(nacosDataId, group, JacksonUtils.toJson(metadataMap)); + if (flag) { + log.info("publish metaData {} success", metadataMap); + } else { + log.error("publish metaData {} fail", metadataMap); + } + } catch (NacosException e) { + log.error("failed to publish data to nacos", e); + throw new RuntimeException(e); + } + } + + @Override + public void removeMetaData(String key) { + + } + + @Override + public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws MetaException { + try { + String[] ipPort = eventMeshRegisterInfo.getEndPoint().split(NacosConstant.IP_PORT_SEPARATOR); + if (ipPort.length < 2) { + return false; + } + 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(); + nacosNamingService.registerInstance(eventMeshName, eventMeshRegisterInfo.getProtocolType() + "-" + + NacosConstant.GROUP, instance); + eventMeshRegisterInfoMap.put(eventMeshName, eventMeshRegisterInfo); + } catch (NacosException e) { + log.error("[NacosRegistryService][register] error", e); + throw new MetaException(e.getMessage()); + } + log.info("EventMesh successfully registered to nacos"); + return true; + } + + @Override + public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws MetaException { + 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); + nacosNamingService.deregisterInstance(eventMeshName, eventMeshUnRegisterInfo.getProtocolType() + + "-" + NacosConstant.GROUP, instance); + eventMeshRegisterInfoMap.remove(eventMeshName); + } catch (NacosException e) { + log.error("[NacosRegistryService][unRegister] error", e); + throw new MetaException(e.getMessage()); + } + log.info("EventMesh successfully logout to nacos"); + return true; + } +} diff --git a/eventmesh-meta/eventmesh-meta-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService b/eventmesh-meta/eventmesh-meta-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService new file mode 100644 index 0000000000..44b15a5198 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService @@ -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.meta.nacos.service.NacosMetaService \ No newline at end of file diff --git a/eventmesh-meta/eventmesh-meta-nacos/src/test/java/org/apache/eventmesh/registry/nacos/service/NacosMetaServiceTest.java b/eventmesh-meta/eventmesh-meta-nacos/src/test/java/org/apache/eventmesh/registry/nacos/service/NacosMetaServiceTest.java new file mode 100644 index 0000000000..1065ab4be5 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-nacos/src/test/java/org/apache/eventmesh/registry/nacos/service/NacosMetaServiceTest.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.registry.nacos.service; + +import static org.apache.eventmesh.common.Constants.HTTP; + +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.meta.nacos.service.NacosMetaService; + +import java.lang.reflect.Field; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class NacosMetaServiceTest { + + @Mock + private EventMeshRegisterInfo eventMeshRegisterInfo; + @Mock + private EventMeshUnRegisterInfo eventMeshUnRegisterInfo; + + private NacosMetaService nacosMetaService; + + @BeforeEach + public void setUp() { + nacosMetaService = new NacosMetaService(); + CommonConfiguration configuration = new CommonConfiguration(); + configuration.setMetaStorageAddr("127.0.0.1"); + configuration.setEventMeshMetaStoragePluginPassword("nacos"); + configuration.setEventMeshMetaStoragePluginUsername("nacos"); + ConfigurationContextUtil.putIfAbsent(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"); + } + + @AfterEach + public void after() { + nacosMetaService.shutdown(); + } + + @Test + public void testInit() { + nacosMetaService.init(); + nacosMetaService.start(); + Assertions.assertNotNull(nacosMetaService.getServerAddr()); + } + + @Test + public void testStart() { + nacosMetaService.init(); + nacosMetaService.start(); + Assertions.assertNotNull(nacosMetaService.getNacosNamingService()); + + } + + @Test + public void testShutdown() throws NoSuchFieldException, IllegalAccessException { + nacosMetaService.init(); + nacosMetaService.start(); + nacosMetaService.shutdown(); + + Class nacosRegistryServiceClass = NacosMetaService.class; + Field initStatus = nacosRegistryServiceClass.getDeclaredField("initStatus"); + initStatus.setAccessible(true); + Object initStatusField = initStatus.get(nacosMetaService); + + Field startStatus = nacosRegistryServiceClass.getDeclaredField("startStatus"); + startStatus.setAccessible(true); + Object startStatusField = startStatus.get(nacosMetaService); + + Assertions.assertFalse((Boolean.parseBoolean(initStatusField.toString()))); + Assertions.assertFalse((Boolean.parseBoolean(startStatusField.toString()))); + } +} diff --git a/eventmesh-meta/eventmesh-meta-zookeeper/build.gradle b/eventmesh-meta/eventmesh-meta-zookeeper/build.gradle new file mode 100644 index 0000000000..1d8c871e2b --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-zookeeper/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 { + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + implementation 'org.apache.zookeeper:zookeeper' + implementation 'org.apache.curator:curator-client' + implementation 'org.apache.curator:curator-framework' + implementation 'org.apache.curator:curator-recipes' + + implementation project(":eventmesh-meta:eventmesh-meta-api") + implementation project(":eventmesh-common") + + testImplementation 'org.mockito:mockito-core' + testImplementation 'org.mockito:mockito-junit-jupiter' + testImplementation 'org.apache.curator:curator-test' +} diff --git a/eventmesh-meta/eventmesh-meta-zookeeper/gradle.properties b/eventmesh-meta/eventmesh-meta-zookeeper/gradle.properties new file mode 100644 index 0000000000..d987fd1a0c --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-zookeeper/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=metaStorage +pluginName=zookeeper \ No newline at end of file diff --git a/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/config/ZKRegistryConfiguration.java b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/config/ZKRegistryConfiguration.java new file mode 100644 index 0000000000..bec8faae7e --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/config/ZKRegistryConfiguration.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.meta.zookeeper.config; + +import org.apache.eventmesh.common.config.Config; +import org.apache.eventmesh.common.config.ConfigFiled; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@Config(prefix = "eventMesh.registry.zookeeper") +public class ZKRegistryConfiguration { + + @ConfigFiled(field = "scheme") + private String scheme; + + @ConfigFiled(field = "auth") + private String auth; + + @ConfigFiled(field = "connectionTimeoutMs") + private Integer connectionTimeoutMs = 5000; + + @ConfigFiled(field = "sessionTimeoutMs") + private Integer sessionTimeoutMs = 40000; + + // Fully qualified name of RetryPolicy implementation + @ConfigFiled(field = "retryPolicy.class") + private String retryPolicyClass; + + @ConfigFiled(field = "retryPolicy.baseSleepTimeMs") + private Integer baseSleepTimeMs = 1000; + + @ConfigFiled(field = "retryPolicy.maxRetries") + private Integer maxRetries = 5; + + @ConfigFiled(field = "retryPolicy.maxSleepTimeMs") + private Integer maxSleepTimeMs = 5000; + + @ConfigFiled(field = "retryPolicy.retryIntervalMs") + private Integer retryIntervalTimeMs = 1000; + + @ConfigFiled(field = "retryPolicy.nTimes") + private Integer retryNTimes = 10; + + @ConfigFiled(field = "retryPolicy.sleepMsBetweenRetries") + private Integer sleepMsBetweenRetries = 1000; + +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/java/org/apache/eventmesh/registry/zookeeper/constant/ZookeeperConstant.java b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/constant/ZookeeperConstant.java similarity index 94% rename from eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/java/org/apache/eventmesh/registry/zookeeper/constant/ZookeeperConstant.java rename to eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/constant/ZookeeperConstant.java index 4369ff14fa..8ed983befc 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/java/org/apache/eventmesh/registry/zookeeper/constant/ZookeeperConstant.java +++ b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/constant/ZookeeperConstant.java @@ -15,8 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.zookeeper.constant; - +package org.apache.eventmesh.meta.zookeeper.constant; public class ZookeeperConstant { diff --git a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/java/org/apache/eventmesh/registry/zookeeper/pojo/EventMeshInstance.java b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/pojo/EventMeshInstance.java similarity index 95% rename from eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/java/org/apache/eventmesh/registry/zookeeper/pojo/EventMeshInstance.java rename to eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/pojo/EventMeshInstance.java index 46f0eb27e8..fbe27ab75a 100644 --- a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/java/org/apache/eventmesh/registry/zookeeper/pojo/EventMeshInstance.java +++ b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/pojo/EventMeshInstance.java @@ -15,8 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.registry.zookeeper.pojo; - +package org.apache.eventmesh.meta.zookeeper.pojo; import java.io.Serializable; import java.util.Map; @@ -36,5 +35,4 @@ public class EventMeshInstance implements Serializable { private Map metaData; - } diff --git a/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/service/ZookeeperMetaService.java b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/service/ZookeeperMetaService.java new file mode 100644 index 0000000000..5cee22d9c0 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/java/org/apache/eventmesh/meta/zookeeper/service/ZookeeperMetaService.java @@ -0,0 +1,376 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.meta.zookeeper.service; + +import org.apache.eventmesh.api.exception.MetaException; +import org.apache.eventmesh.api.meta.MetaService; +import org.apache.eventmesh.api.meta.MetaServiceListener; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.config.ConfigService; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.meta.zookeeper.config.ZKRegistryConfiguration; +import org.apache.eventmesh.meta.zookeeper.constant.ZookeeperConstant; +import org.apache.eventmesh.meta.zookeeper.pojo.EventMeshInstance; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.curator.RetryPolicy; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.framework.CuratorFrameworkFactory.Builder; +import org.apache.curator.retry.BoundedExponentialBackoffRetry; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.curator.retry.RetryForever; +import org.apache.curator.retry.RetryNTimes; +import org.apache.zookeeper.CreateMode; +import org.apache.zookeeper.data.Stat; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ZookeeperMetaService implements MetaService { + + private final AtomicBoolean initStatus = new AtomicBoolean(false); + + private final AtomicBoolean startStatus = new AtomicBoolean(false); + + @Getter + private String serverAddr; + + @Getter + public CuratorFramework zkClient; + + private ConcurrentMap eventMeshRegisterInfoMap; + + private ZKRegistryConfiguration zkConfig; + + @Override + public void init() throws MetaException { + + if (!initStatus.compareAndSet(false, true)) { + log.warn("[ZookeeperRegistryService] has been init"); + return; + } + eventMeshRegisterInfoMap = new ConcurrentHashMap<>(ConfigurationContextUtil.KEYS.size()); + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); + if (null == commonConfiguration) { + continue; + } + if (StringUtils.isBlank(commonConfiguration.getMetaStorageAddr())) { + throw new MetaException("meta storage address cannot be null"); + } + this.serverAddr = commonConfiguration.getMetaStorageAddr(); + break; + } + ZKRegistryConfiguration zkConfig = ConfigService.getInstance().buildConfigInstance(ZKRegistryConfiguration.class); + this.zkConfig = zkConfig; + } + + @Override + public void start() throws MetaException { + + if (!startStatus.compareAndSet(false, true)) { + log.warn("[ZookeeperRegistryService] has been start"); + return; + } + try { + zkClient = buildZkClient(); + zkClient.start(); + } catch (Exception e) { + throw new MetaException("ZookeeperRegistry starting failed", e); + } + } + + private CuratorFramework buildZkClient() throws ClassNotFoundException { + Builder builder = CuratorFrameworkFactory.builder() + .connectString(serverAddr) + .namespace(ZookeeperConstant.NAMESPACE); + if (zkConfig == null) { + builder.retryPolicy(new ExponentialBackoffRetry(1000, 5)); + return builder.build(); + } + builder.retryPolicy(createRetryPolicy()); + String scheme = zkConfig.getScheme(); + String auth = zkConfig.getAuth(); + if (!StringUtils.isAnyBlank(scheme, auth)) { + builder.authorization(scheme, auth.getBytes(Constants.DEFAULT_CHARSET)); + } + Optional.ofNullable(zkConfig.getConnectionTimeoutMs()).ifPresent((timeout) -> builder.connectionTimeoutMs(timeout)); + Optional.ofNullable(zkConfig.getSessionTimeoutMs()).ifPresent((timeout) -> builder.sessionTimeoutMs(timeout)); + return builder.build(); + } + + private RetryPolicy createRetryPolicy() throws ClassNotFoundException { + String retryPolicyClass = zkConfig.getRetryPolicyClass(); + if (StringUtils.isBlank(retryPolicyClass)) { + return new ExponentialBackoffRetry(1000, 5); + } + Class clazz = Class.forName(retryPolicyClass); + if (clazz == ExponentialBackoffRetry.class) { + return new ExponentialBackoffRetry( + getOrDefault(zkConfig.getBaseSleepTimeMs(), 1000, Integer.class), + getOrDefault(zkConfig.getMaxRetries(), 5, Integer.class)); + } else if (clazz == BoundedExponentialBackoffRetry.class) { + return new BoundedExponentialBackoffRetry( + getOrDefault(zkConfig.getBaseSleepTimeMs(), 1000, Integer.class), + getOrDefault(zkConfig.getMaxSleepTimeMs(), 5000, Integer.class), + getOrDefault(zkConfig.getMaxRetries(), 5, Integer.class)); + } else if (clazz == RetryForever.class) { + return new RetryForever( + getOrDefault(zkConfig.getRetryIntervalTimeMs(), 1000, Integer.class)); + } else if (clazz == RetryNTimes.class) { + return new RetryNTimes( + getOrDefault(zkConfig.getRetryNTimes(), 10, Integer.class), + getOrDefault(zkConfig.getSleepMsBetweenRetries(), 1000, Integer.class)); + } else { + throw new IllegalArgumentException("Unsupported retry policy: " + retryPolicyClass); + } + } + + private T getOrDefault(T value, T defaultValue, Class clazz) { + if (value != null) { + return value; + } + return defaultValue; + } + + @Override + public void shutdown() throws MetaException { + if (!initStatus.compareAndSet(true, false)) { + return; + } + if (!startStatus.compareAndSet(true, false)) { + return; + } + if (null != zkClient) { + zkClient.close(); + } + log.info("ZookeeperRegistryService closed"); + } + + @Override + public List findEventMeshInfoByCluster(String clusterName) throws MetaException { + List eventMeshDataInfoList = new ArrayList<>(); + for (String key : ConfigurationContextUtil.KEYS) { + CommonConfiguration configuration = ConfigurationContextUtil.get(key); + if (Objects.isNull(configuration)) { + continue; + } + String eventMeshName = configuration.getEventMeshName(); + try { + String serviceName = eventMeshName.concat("-").concat(key); + String servicePath = formatServicePath(clusterName, serviceName); + + List instances = zkClient.getChildren() + .forPath(servicePath); + + if (CollectionUtils.isEmpty(instances)) { + continue; + } + + for (String endpoint : instances) { + String instancePath = servicePath.concat(ZookeeperConstant.PATH_SEPARATOR).concat(endpoint); + + Stat stat = new Stat(); + byte[] data; + try { + data = zkClient.getData() + .storingStatIn(stat) + .forPath(instancePath); + } catch (Exception e) { + log.warn("[ZookeeperRegistryService][findEventMeshInfoByCluster] failed for path: {}", instancePath, e); + continue; + } + + EventMeshInstance eventMeshInstance = JsonUtils.parseObject(new String(data, StandardCharsets.UTF_8), EventMeshInstance.class); + + EventMeshDataInfo eventMeshDataInfo = + new EventMeshDataInfo(clusterName, serviceName, endpoint, stat.getMtime(), + Objects.requireNonNull(eventMeshInstance, "instance must not be Null").getMetaData()); + + eventMeshDataInfoList.add(eventMeshDataInfo); + } + + } catch (Exception e) { + throw new MetaException("ZookeeperRegistry findEventMeshInfoByCluster failed", e); + } + + } + return eventMeshDataInfoList; + } + + @Override + public List findAllEventMeshInfo() throws MetaException { + List eventMeshDataInfoList = new ArrayList<>(); + + for (Map.Entry entry : eventMeshRegisterInfoMap.entrySet()) { + + String serviceName = entry.getKey(); + String clusterName = entry.getValue().getEventMeshClusterName(); + try { + String servicePath = formatServicePath(clusterName, serviceName); + + List instances = zkClient.getChildren() + .forPath(servicePath); + + if (CollectionUtils.isEmpty(instances)) { + continue; + } + + for (String endpoint : instances) { + String instancePath = servicePath.concat(ZookeeperConstant.PATH_SEPARATOR).concat(endpoint); + + Stat stat = new Stat(); + byte[] data; + try { + data = zkClient.getData() + .storingStatIn(stat) + .forPath(instancePath); + } catch (Exception e) { + log.warn("[ZookeeperRegistryService][findAllEventMeshInfo] failed for path: {}", instancePath, e); + continue; + } + + EventMeshInstance eventMeshInstance = JsonUtils.parseObject(new String(data, StandardCharsets.UTF_8), EventMeshInstance.class); + + EventMeshDataInfo eventMeshDataInfo = + new EventMeshDataInfo(clusterName, serviceName, endpoint, stat.getMtime(), + Objects.requireNonNull(eventMeshInstance, "instance must not be Null").getMetaData()); + + eventMeshDataInfoList.add(eventMeshDataInfo); + } + + } catch (Exception e) { + throw new MetaException("ZookeeperRegistry findAllEventMeshInfo failed", e); + } + } + return eventMeshDataInfoList; + } + + @Override + public void registerMetadata(Map metadataMap) { + for (Map.Entry eventMeshRegisterInfo : eventMeshRegisterInfoMap.entrySet()) { + EventMeshRegisterInfo registerInfo = eventMeshRegisterInfo.getValue(); + registerInfo.setMetadata(metadataMap); + this.register(registerInfo); + } + } + + @Override + public Map getMetaData(String key, boolean fuzzyEnabled) { + return null; + } + + // todo: to be implemented + @Override + public void getMetaDataWithListener(MetaServiceListener metaServiceListener, String key) { + + } + + @Override + public void updateMetaData(Map metadataMap) { + + } + + @Override + public void removeMetaData(String key) { + + } + + @Override + public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws MetaException { + try { + String[] ipPort = eventMeshRegisterInfo.getEndPoint().split(ZookeeperConstant.IP_PORT_SEPARATOR); + if (null == ipPort || ipPort.length < 2) { + return false; + } + String ip = ipPort[0]; + int port = Integer.parseInt(ipPort[1]); + String eventMeshName = eventMeshRegisterInfo.getEventMeshName(); + String eventMeshClusterName = eventMeshRegisterInfo.getEventMeshClusterName(); + Map> instanceNumMap = eventMeshRegisterInfo.getEventMeshInstanceNumMap(); + Map metadata = eventMeshRegisterInfo.getMetadata(); + + EventMeshInstance eventMeshInstance = new EventMeshInstance(); + eventMeshInstance.setIp(ip); + eventMeshInstance.setPort(port); + eventMeshInstance.setInstanceNumMap(instanceNumMap); + eventMeshInstance.setMetaData(metadata); + + // clusterName/eventMeshName/ip:port + final String path = formatInstancePath(eventMeshClusterName, eventMeshName, eventMeshRegisterInfo.getEndPoint()); + + zkClient.create() + .orSetData() + .creatingParentsIfNeeded() + .withMode(CreateMode.EPHEMERAL) + .forPath(path, + Objects.requireNonNull(JsonUtils.toJSONString(eventMeshInstance), "instance must not be Null").getBytes(StandardCharsets.UTF_8)); + + eventMeshRegisterInfoMap.put(eventMeshName, eventMeshRegisterInfo); + } catch (Exception e) { + throw new MetaException("ZookeeperRegistry register failed", e); + } + log.info("EventMesh successfully registered to zookeeper"); + return true; + } + + @Override + public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws MetaException { + try { + String eventMeshName = eventMeshUnRegisterInfo.getEventMeshName(); + String eventMeshClusterName = eventMeshUnRegisterInfo.getEventMeshClusterName(); + + String path = formatInstancePath(eventMeshClusterName, eventMeshName, eventMeshUnRegisterInfo.getEndPoint()); + + zkClient.delete().forPath(path); + } catch (Exception e) { + throw new MetaException("ZookeeperRegistry unRegister failed", e); + } + log.info("EventMesh successfully logout to zookeeper"); + return true; + } + + private String formatInstancePath(String clusterName, String serviceName, String endPoint) { + return ZookeeperConstant.PATH_SEPARATOR.concat(clusterName) + .concat(ZookeeperConstant.PATH_SEPARATOR).concat(serviceName) + .concat(ZookeeperConstant.PATH_SEPARATOR).concat(endPoint); + } + + private String formatServicePath(String clusterName, String serviceName) { + return ZookeeperConstant.PATH_SEPARATOR.concat(clusterName) + .concat(ZookeeperConstant.PATH_SEPARATOR).concat(serviceName); + } +} diff --git a/eventmesh-meta/eventmesh-meta-zookeeper/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService new file mode 100644 index 0000000000..66bf19b4f9 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-zookeeper/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.meta.MetaService @@ -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. + +zookeeper=org.apache.eventmesh.meta.zookeeper.service.ZookeeperMetaService \ No newline at end of file diff --git a/eventmesh-meta/eventmesh-meta-zookeeper/src/test/java/org/apache/eventmesh/registry/zookeeper/service/ZookeeperMetaServiceTest.java b/eventmesh-meta/eventmesh-meta-zookeeper/src/test/java/org/apache/eventmesh/registry/zookeeper/service/ZookeeperMetaServiceTest.java new file mode 100644 index 0000000000..12830ae237 --- /dev/null +++ b/eventmesh-meta/eventmesh-meta-zookeeper/src/test/java/org/apache/eventmesh/registry/zookeeper/service/ZookeeperMetaServiceTest.java @@ -0,0 +1,180 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.zookeeper.service; + +import static org.apache.eventmesh.common.Constants.HTTP; + +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.meta.zookeeper.service.ZookeeperMetaService; + +import org.apache.curator.test.TestingServer; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; + +import com.google.common.collect.Maps; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class ZookeeperMetaServiceTest { + + @Mock + private EventMeshRegisterInfo eventMeshRegisterInfo; + @Mock + private EventMeshUnRegisterInfo eventMeshUnRegisterInfo; + + private ZookeeperMetaService zkRegistryService; + + private TestingServer testingServer; + + @BeforeEach + public void setUp() throws Exception { + testingServer = new TestingServer(1500, true); + testingServer.start(); + + zkRegistryService = new ZookeeperMetaService(); + CommonConfiguration configuration = new CommonConfiguration(); + configuration.setMetaStorageAddr("127.0.0.1:1500"); + configuration.setEventMeshName("eventmesh"); + ConfigurationContextUtil.putIfAbsent(HTTP, configuration); + + Mockito.when(eventMeshRegisterInfo.getEventMeshClusterName()).thenReturn("eventmeshCluster"); + Mockito.when(eventMeshRegisterInfo.getEventMeshName()).thenReturn("eventmesh-" + HTTP); + Mockito.when(eventMeshRegisterInfo.getEndPoint()).thenReturn("127.0.0.1:8848"); + Mockito.when(eventMeshRegisterInfo.getEventMeshInstanceNumMap()).thenReturn(Maps.newHashMap()); + HashMap metaData = Maps.newHashMap(); + metaData.put("test", "a"); + Mockito.when(eventMeshRegisterInfo.getMetadata()).thenReturn(metaData); + + Mockito.when(eventMeshUnRegisterInfo.getEventMeshClusterName()).thenReturn("eventmeshCluster"); + Mockito.when(eventMeshUnRegisterInfo.getEventMeshName()).thenReturn("eventmesh-" + HTTP); + Mockito.when(eventMeshUnRegisterInfo.getEndPoint()).thenReturn("127.0.0.1:8848"); + } + + @AfterEach + public void after() throws Exception { + zkRegistryService.shutdown(); + testingServer.close(); + } + + @Test + public void testInit() { + zkRegistryService.init(); + zkRegistryService.start(); + Assertions.assertNotNull(zkRegistryService.getServerAddr()); + } + + @Test + public void testStart() { + zkRegistryService.init(); + zkRegistryService.start(); + Assertions.assertNotNull(zkRegistryService.getZkClient()); + } + + @Test + public void testShutdown() throws NoSuchFieldException, IllegalAccessException { + zkRegistryService.init(); + zkRegistryService.start(); + zkRegistryService.shutdown(); + + Class zkRegistryServiceClass = ZookeeperMetaService.class; + Field initStatus = zkRegistryServiceClass.getDeclaredField("initStatus"); + initStatus.setAccessible(true); + Object initStatusField = initStatus.get(zkRegistryService); + + Field startStatus = zkRegistryServiceClass.getDeclaredField("startStatus"); + startStatus.setAccessible(true); + Object startStatusField = startStatus.get(zkRegistryService); + + Assertions.assertFalse((Boolean.parseBoolean(initStatusField.toString()))); + Assertions.assertFalse((Boolean.parseBoolean(startStatusField.toString()))); + } + + @Test + public void testFindEventMeshInfoByCluster() { + zkRegistryService.init(); + zkRegistryService.start(); + zkRegistryService.register(eventMeshRegisterInfo); + + final List result = zkRegistryService.findEventMeshInfoByCluster(eventMeshRegisterInfo.getEventMeshClusterName()); + + Assertions.assertNotNull(result); + } + + @Test + public void testFindAllEventMeshInfo() { + zkRegistryService.init(); + zkRegistryService.start(); + zkRegistryService.register(eventMeshRegisterInfo); + + List result = zkRegistryService.findAllEventMeshInfo(); + + Assertions.assertNotNull(result); + } + + @Test + public void testRegisterMetadata() { + zkRegistryService.init(); + zkRegistryService.start(); + zkRegistryService.register(eventMeshRegisterInfo); + Map metaData = Maps.newConcurrentMap(); + metaData.put("test", "a"); + zkRegistryService.registerMetadata(metaData); + List infoList = + zkRegistryService.findEventMeshInfoByCluster(eventMeshRegisterInfo.getEventMeshClusterName()); + + Assertions.assertNotNull(infoList); + } + + @Test + public void testRegister() { + zkRegistryService.init(); + zkRegistryService.start(); + zkRegistryService.register(eventMeshRegisterInfo); + } + + @Test + public void testUnRegister() { + zkRegistryService.init(); + zkRegistryService.start(); + boolean register = zkRegistryService.register(eventMeshRegisterInfo); + + Assertions.assertTrue(register); + + boolean unRegister = zkRegistryService.unRegister(eventMeshUnRegisterInfo); + + Assertions.assertTrue(unRegister); + } +} diff --git a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/test/resources/log4j.properties b/eventmesh-meta/eventmesh-meta-zookeeper/src/test/resources/log4j.properties similarity index 100% rename from eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/test/resources/log4j.properties rename to eventmesh-meta/eventmesh-meta-zookeeper/src/test/resources/log4j.properties diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/build.gradle b/eventmesh-metrics-plugin/eventmesh-metrics-api/build.gradle index df03e7c632..3f433bac4e 100644 --- a/eventmesh-metrics-plugin/eventmesh-metrics-api/build.gradle +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/build.gradle @@ -27,5 +27,4 @@ dependencies { testAnnotationProcessor 'org.projectlombok:lombok' testImplementation "org.mockito:mockito-core" - testImplementation "org.mockito:mockito-inline" } 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 index 34de770820..e09ff63884 100644 --- 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 @@ -19,9 +19,10 @@ 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 java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import lombok.extern.slf4j.Slf4j; @@ -35,7 +36,7 @@ public class HttpSummaryMetrics implements Metric { private final AtomicLong wholeRequestNum = new AtomicLong(0); - //cumulative value + // cumulative value private final AtomicLong httpDiscard = new AtomicLong(0); private final AtomicLong maxCost = new AtomicLong(0); @@ -104,20 +105,20 @@ public class HttpSummaryMetrics implements Metric { private final ThreadPoolExecutor pushMsgExecutor; - private final DelayQueue httpFailedQueue; + private final RetrySummaryMetrics retrySummaryMetrics; + private Lock lock = new ReentrantLock(); public HttpSummaryMetrics(final ThreadPoolExecutor batchMsgExecutor, final ThreadPoolExecutor sendMsgExecutor, final ThreadPoolExecutor pushMsgExecutor, - final DelayQueue httpFailedQueue) { + final RetrySummaryMetrics retrySummaryMetrics) { this.batchMsgExecutor = batchMsgExecutor; this.sendMsgExecutor = sendMsgExecutor; this.pushMsgExecutor = pushMsgExecutor; - this.httpFailedQueue = httpFailedQueue; + this.retrySummaryMetrics = retrySummaryMetrics; } - public float avgHTTPCost() { return (wholeRequestNum.longValue() == 0L) ? 0f : wholeCost / wholeRequestNum.longValue(); } @@ -139,20 +140,37 @@ public void recordHTTPDiscard() { } public void snapshotHTTPTPS() { - Integer tps = httpRequestPerSecond.intValue(); - httpRequestTPSSnapshots.add(tps); - httpRequestPerSecond.set(0); - if (httpRequestTPSSnapshots.size() > STATIC_PERIOD / 1000) { - httpRequestTPSSnapshots.removeFirst(); + try { + lock.lock(); + Integer tps = httpRequestPerSecond.intValue(); + httpRequestTPSSnapshots.add(tps); + httpRequestPerSecond.set(0); + if (httpRequestTPSSnapshots.size() > STATIC_PERIOD / 1000) { + httpRequestTPSSnapshots.removeFirst(); + } + } finally { + lock.unlock(); } } public float maxHTTPTPS() { - return Collections.max(httpRequestTPSSnapshots); + try { + lock.lock(); + float tps = Collections.max(httpRequestTPSSnapshots); + return tps; + } finally { + lock.unlock(); + } } public float avgHTTPTPS() { - return avg(httpRequestTPSSnapshots); + try { + lock.lock(); + float tps = avg(httpRequestTPSSnapshots); + return tps; + } finally { + lock.unlock(); + } } public void recordHTTPReqResTimeCost(long cost) { @@ -171,7 +189,6 @@ public void httpStatInfoClear() { httpDecodeTimeCost = 0f; } - public void recordDecodeTimeCost(long cost) { httpDecodeNum.incrementAndGet(); httpDecodeTimeCost = httpDecodeTimeCost + cost; @@ -181,7 +198,6 @@ public float avgHTTPBodyDecodeCost() { return (httpDecodeNum.longValue() == 0L) ? 0f : httpDecodeTimeCost / httpDecodeNum.longValue(); } - public void recordSendBatchMsgDiscard(long delta) { sendBatchMsgDiscardNumSum.addAndGet(delta); } @@ -233,7 +249,6 @@ public long getSendBatchMsgDiscardNumSum() { return sendBatchMsgDiscardNumSum.longValue(); } - public void snapshotSendMsgTPS() { Integer tps = sendMsgNumPerSecond.intValue(); sendMsgTPSSnapshots.add(tps); @@ -295,7 +310,6 @@ public void cleanSendMsgStat() { replyMsgFailNumSum.set(0L); } - public void snapshotPushMsgTPS() { Integer tps = pushMsgNumPerSecond.intValue(); pushMsgTPSSnapshots.add(tps); @@ -358,7 +372,6 @@ public void cleanHttpPushMsgStat() { maxCost.set(0L); } - public void recordBatchSendMsgCost(long cost) { batchSend2MQNum.incrementAndGet(); batchSend2MQWholeCost = batchSend2MQWholeCost + cost; @@ -395,7 +408,6 @@ public void send2MQStatInfoClear() { reply2MQNum.set(0L); } - public int getBatchMsgQueueSize() { return batchMsgExecutor.getQueue().size(); } @@ -408,11 +420,10 @@ public int getPushMsgQueueSize() { return pushMsgExecutor.getQueue().size(); } - public int getHttpRetryQueueSize() { - return httpFailedQueue.size(); + public long getHttpRetryQueueSize() { + return retrySummaryMetrics.getPendingRetryTimeouts(); } - private float avg(LinkedList linkedList) { if (linkedList.isEmpty()) { return 0.0f; diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/RetrySummaryMetrics.java b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/RetrySummaryMetrics.java new file mode 100644 index 0000000000..1962527cae --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/main/java/org/apache/eventmesh/metrics/api/model/RetrySummaryMetrics.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.metrics.api.model; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class RetrySummaryMetrics { + + private long pendingRetryTimeouts; +} 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 index 02d8ec5eb0..1e54c8e758 100644 --- 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 @@ -37,7 +37,7 @@ public class TcpSummaryMetrics implements Metric { private int allConnections; - private int retrySize; + private long retrySize; public TcpSummaryMetrics() { this.client2eventMeshMsgNum = new AtomicInteger(0); @@ -130,11 +130,11 @@ public void setAllConnections(int allConnections) { this.allConnections = allConnections; } - public void setRetrySize(int retrySize) { + public void setRetrySize(long retrySize) { this.retrySize = retrySize; } - public int getRetrySize() { + public long getRetrySize() { return retrySize; } } diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/test/java/org/apache/eventmesh/metrics/api/MetricsPluginFactoryTest.java b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/test/java/org/apache/eventmesh/metrics/api/MetricsPluginFactoryTest.java index b29efefd57..16bb8c86d3 100644 --- a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/test/java/org/apache/eventmesh/metrics/api/MetricsPluginFactoryTest.java +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/test/java/org/apache/eventmesh/metrics/api/MetricsPluginFactoryTest.java @@ -17,14 +17,14 @@ package org.apache.eventmesh.metrics.api; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class MetricsPluginFactoryTest { @Test public void testGetMetricsRegistry_throwException() { - Exception exception = Assert.assertThrows(NullPointerException.class, () -> MetricsPluginFactory.getMetricsRegistry("security")); - Assert.assertTrue(exception.getMessage().contains("is not supported")); + Exception exception = Assertions.assertThrows(NullPointerException.class, () -> MetricsPluginFactory.getMetricsRegistry("security")); + Assertions.assertTrue(exception.getMessage().contains("is not supported")); } } diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/test/java/org/apache/eventmesh/metrics/api/model/GrpcSummaryMetricsTest.java b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/test/java/org/apache/eventmesh/metrics/api/model/GrpcSummaryMetricsTest.java index 83a5cb747a..73a788b6fa 100644 --- a/eventmesh-metrics-plugin/eventmesh-metrics-api/src/test/java/org/apache/eventmesh/metrics/api/model/GrpcSummaryMetricsTest.java +++ b/eventmesh-metrics-plugin/eventmesh-metrics-api/src/test/java/org/apache/eventmesh/metrics/api/model/GrpcSummaryMetricsTest.java @@ -17,8 +17,8 @@ package org.apache.eventmesh.metrics.api.model; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class GrpcSummaryMetricsTest { @@ -31,12 +31,12 @@ public void testTpsCalculate() { grpcSummaryMetrics.getClient2EventMeshMsgNum().addAndGet(1024); grpcSummaryMetrics.refreshTpsMetrics(500); - Assert.assertEquals(256, grpcSummaryMetrics.getEventMesh2ClientTPS()); - Assert.assertEquals(512, grpcSummaryMetrics.getEventMesh2MqTPS()); - Assert.assertEquals(1024, grpcSummaryMetrics.getMq2EventMeshTPS()); - Assert.assertEquals(2048, grpcSummaryMetrics.getClient2EventMeshTPS()); + Assertions.assertEquals(256, grpcSummaryMetrics.getEventMesh2ClientTPS()); + Assertions.assertEquals(512, grpcSummaryMetrics.getEventMesh2MqTPS()); + Assertions.assertEquals(1024, grpcSummaryMetrics.getMq2EventMeshTPS()); + Assertions.assertEquals(2048, grpcSummaryMetrics.getClient2EventMeshTPS()); grpcSummaryMetrics.clearAllMessageCounter(); - Assert.assertEquals(0, grpcSummaryMetrics.getEventMesh2ClientMsgNum().get()); + Assertions.assertEquals(0, grpcSummaryMetrics.getEventMesh2ClientMsgNum().get()); } } 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 index 99e79923c0..6fd0b9acdb 100644 --- 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 @@ -57,7 +57,7 @@ public void start() { .builder().setMetricProducer(sdkMeterProvider).buildAndRegister(); int port = prometheusConfiguration.getEventMeshPrometheusPort(); try { - //Use the daemon thread to start an HTTP server to serve the default Prometheus registry. + // 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()); diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusGrpcExporter.java b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusGrpcExporter.java index a99da83b66..ca61f9add5 100644 --- a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusGrpcExporter.java +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/metrics/PrometheusGrpcExporter.java @@ -17,40 +17,44 @@ package org.apache.eventmesh.metrics.prometheus.metrics; +import static org.apache.eventmesh.common.Constants.GRPC; +import static org.apache.eventmesh.metrics.prometheus.utils.PrometheusExporterConstants.METRICS_GRPC_PREFIX; +import static org.apache.eventmesh.metrics.prometheus.utils.PrometheusExporterUtils.join; +import static org.apache.eventmesh.metrics.prometheus.utils.PrometheusExporterUtils.observeOfValue; + import org.apache.eventmesh.metrics.api.model.GrpcSummaryMetrics; -import java.util.function.Supplier; +import java.util.Map; +import java.util.function.Function; import io.opentelemetry.api.metrics.GlobalMeterProvider; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; + +import com.google.common.collect.ImmutableMap; import lombok.experimental.UtilityClass; @UtilityClass public class PrometheusGrpcExporter { - private static final String UNIT = "GRPC"; - private static final String METRICS_NAME_PREFIX = "eventmesh.grpc."; - - private void observeOfValue(Meter meter, String name, String desc, Supplier supplier) { - meter.doubleValueObserverBuilder(METRICS_NAME_PREFIX + name) - .setDescription(desc) - .setUnit(UNIT) - .setUpdater(result -> result.observe(supplier.get(), Labels.empty())) - .build(); - } + /** + * Map structure : [metric name, description of name] -> the method of get corresponding metric. + */ + private final Map> paramPairs = ImmutableMap + .>builder() + .put(join("sub.topic.num", "get sub topic num."), GrpcSummaryMetrics::getSubscribeTopicNum) + .put(join("retry.queue.size", "get size of retry queue."), GrpcSummaryMetrics::getRetrySize) + .put(join("server.tps", "get size of retry queue."), GrpcSummaryMetrics::getClient2EventMeshTPS) + .put(join("client.tps", "get tps of eventMesh to mq."), GrpcSummaryMetrics::getEventMesh2ClientTPS) + .put(join("mq.provider.tps", "get tps of eventMesh to mq."), GrpcSummaryMetrics::getEventMesh2MqTPS) + .put(join("mq.consumer.tps", "get tps of eventMesh to mq."), GrpcSummaryMetrics::getMq2EventMeshTPS) + .build(); public static void export(final String meterName, final GrpcSummaryMetrics summaryMetrics) { final Meter meter = GlobalMeterProvider.getMeter(meterName); - observeOfValue(meter, "sub.topic.num", "get sub topic num.", summaryMetrics::getSubscribeTopicNum); - observeOfValue(meter, "retry.queue.size", "get size of retry queue.", summaryMetrics::getRetrySize); - - observeOfValue(meter, "server.tps", "get size of retry queue.", summaryMetrics::getClient2EventMeshTPS); - observeOfValue(meter, "client.tps", "get tps of eventMesh to mq.", summaryMetrics::getEventMesh2ClientTPS); - - observeOfValue(meter, "mq.provider.tps", "get tps of eventMesh to mq.", summaryMetrics::getEventMesh2MqTPS); - observeOfValue(meter, "mq.consumer.tps", "get tps of eventMesh to mq.", summaryMetrics::getMq2EventMeshTPS); + paramPairs.forEach( + (metricInfo, getMetric) -> observeOfValue(meter, METRICS_GRPC_PREFIX + metricInfo[0], metricInfo[1], + GRPC, summaryMetrics, getMetric, GrpcSummaryMetrics.class)); } } 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 index 0f87aa8eaf..a09cb074d9 100644 --- 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 @@ -17,282 +17,104 @@ package org.apache.eventmesh.metrics.prometheus.metrics; +import static org.apache.eventmesh.common.Constants.HTTP; +import static org.apache.eventmesh.metrics.prometheus.utils.PrometheusExporterUtils.join; +import static org.apache.eventmesh.metrics.prometheus.utils.PrometheusExporterUtils.observeOfValue; + import org.apache.eventmesh.metrics.api.model.HttpSummaryMetrics; +import java.util.Map; +import java.util.function.Function; + import io.opentelemetry.api.metrics.GlobalMeterProvider; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; + +import com.google.common.collect.ImmutableMap; import lombok.experimental.UtilityClass; @UtilityClass public class PrometheusHttpExporter { - public static void export(String name, HttpSummaryMetrics summaryMetrics) { + /** + * Map structure : [metric name, description of name] -> the method of get corresponding metric. + */ + private final Map> paramPairs = ImmutableMap + .>builder() + // maxHTTPTPS + .put(join("eventmesh.http.request.tps.max", "max TPS of HTTP."), HttpSummaryMetrics::maxHTTPTPS) + // avgHTTPTPS + .put(join("eventmesh.http.request.tps.avg", "avg TPS of HTTP."), HttpSummaryMetrics::avgHTTPTPS) + // maxHTTPCost + .put(join("eventmesh.http.request.cost.max", "max cost of HTTP."), HttpSummaryMetrics::maxHTTPCost) + // avgHTTPCost + .put(join("eventmesh.http.request.cost.avg", "avg cost of HTTP."), HttpSummaryMetrics::avgHTTPCost) + // avgHTTPBodyDecodeCost + .put(join("eventmesh.http.body.decode.cost.avg", "avg body decode cost of HTTP."), HttpSummaryMetrics::avgHTTPBodyDecodeCost) + // httpDiscard + .put(join("eventmesh.http.request.discard.num", "http request discard num."), HttpSummaryMetrics::getHttpDiscard) + // maxBatchSendMsgTPS + .put(join("eventmesh.batch.send.message.tps.max", "max of batch send message tps."), HttpSummaryMetrics::maxSendBatchMsgTPS) + // avgBatchSendMsgTPS + .put(join("eventmesh.batch.send.message.tps.avg", "avg of batch send message tps."), HttpSummaryMetrics::avgSendBatchMsgTPS) + // sum + .put(join("eventmesh.batch.send.message.num", "sum of batch send message number."), HttpSummaryMetrics::getSendBatchMsgNumSum) + // sumFail + .put(join("eventmesh.batch.send.message.fail.num", "sum of batch send message fail message number."), + HttpSummaryMetrics::getSendBatchMsgFailNumSum) + // sumFailRate + .put(join("eventmesh.batch.send.message.fail.rate", "send batch message fail rate."), HttpSummaryMetrics::getSendBatchMsgFailRate) + // discard + .put(join("eventmesh.batch.send.message.discard.num", "sum of send batch message discard number."), + HttpSummaryMetrics::getSendBatchMsgDiscardNumSum) + // maxSendMsgTPS + .put(join("eventmesh.send.message.tps.max", "max of send message tps."), HttpSummaryMetrics::maxSendMsgTPS) + // avgSendMsgTPS + .put(join("eventmesh.send.message.tps.avg", "avg of send message tps."), HttpSummaryMetrics::avgSendMsgTPS) + // sum + .put(join("eventmesh.send.message.num", "sum of send message number."), HttpSummaryMetrics::getSendMsgNumSum) + // sumFail + .put(join("eventmesh.send.message.fail.num", "sum of send message fail number."), HttpSummaryMetrics::getSendMsgFailNumSum) + // sumFailRate + .put(join("eventmesh.send.message.fail.rate", "send message fail rate."), HttpSummaryMetrics::getSendMsgFailRate) + // replyMsg + .put(join("eventmesh.reply.message.num", "sum of reply message number."), HttpSummaryMetrics::getReplyMsgNumSum) + // replyFail + .put(join("eventmesh.reply.message.fail.num", "sum of reply message fail number."), HttpSummaryMetrics::getReplyMsgFailNumSum) + // maxPushMsgTPS + .put(join("eventmesh.push.message.tps.max", "max of push message tps."), HttpSummaryMetrics::maxPushMsgTPS) + // avgPushMsgTPS + .put(join("eventmesh.push.message.tps.avg", "avg of push message tps."), HttpSummaryMetrics::avgPushMsgTPS) + // sum + .put(join("eventmesh.http.push.message.num", "sum of http push message number."), HttpSummaryMetrics::getHttpPushMsgNumSum) + // sumFail + .put(join("eventmesh.http.push.message.fail.num", "sum of http push message fail number."), HttpSummaryMetrics::getHttpPushFailNumSum) + // sumFailRate + .put(join("eventmesh.http.push.message.fail.rate", "http push message fail rate."), HttpSummaryMetrics::getHttpPushMsgFailRate) + // maxClientLatency + .put(join("eventmesh.http.push.latency.max", "max of http push latency."), HttpSummaryMetrics::maxHTTPPushLatency) + // avgClientLatency + .put(join("eventmesh.http.push.latency.avg", "avg of http push latency."), HttpSummaryMetrics::avgHTTPPushLatency) + // batchMsgQ + .put(join("eventmesh.batch.message.queue.size", "size of batch message queue."), HttpSummaryMetrics::getBatchMsgQueueSize) + // sendMsgQ + .put(join("eventmesh.send.message.queue.size", "size of send message queue."), HttpSummaryMetrics::getSendMsgQueueSize) + // pushMsgQ + .put(join("eventmesh.push.message.queue.size", "size of push message queue."), HttpSummaryMetrics::getPushMsgQueueSize) + // httpRetryQ + .put(join("eventmesh.http.retry.queue.size", "size of http retry queue."), HttpSummaryMetrics::getHttpRetryQueueSize) + // batchAvgSend2MQCost + .put(join("eventmesh.batch.send.message.cost.avg", "avg of batch send message cost."), HttpSummaryMetrics::avgBatchSendMsgCost) + // avgSend2MQCost + .put(join("eventmesh.send.message.cost.avg", "avg of send message cost."), HttpSummaryMetrics::avgSendMsgCost) + // avgReply2MQCost + .put(join("eventmesh.reply.message.cost.avg", "avg of reply message cost."), HttpSummaryMetrics::avgReplyMsgCost) + .build(); + + public 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(); + paramPairs.forEach((metricInfo, getMetric) -> observeOfValue(meter, metricInfo[0], metricInfo[1], + HTTP, summaryMetrics, getMetric, HttpSummaryMetrics.class)); } } 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 index 01edb55496..ff9eef9a4f 100644 --- 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 @@ -17,73 +17,53 @@ package org.apache.eventmesh.metrics.prometheus.metrics; +import static org.apache.eventmesh.common.Constants.TCP; +import static org.apache.eventmesh.metrics.prometheus.utils.PrometheusExporterConstants.METRICS_TCP_PREFIX; +import static org.apache.eventmesh.metrics.prometheus.utils.PrometheusExporterUtils.join; +import static org.apache.eventmesh.metrics.prometheus.utils.PrometheusExporterUtils.observeOfValue; + import org.apache.eventmesh.metrics.api.model.TcpSummaryMetrics; +import java.util.Map; +import java.util.function.Function; + import io.opentelemetry.api.metrics.GlobalMeterProvider; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.api.metrics.common.Labels; + +import com.google.common.collect.ImmutableMap; 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(); + /** + * Map structure : [metric name, description of name] -> the method of get corresponding metric. + */ + private final Map> paramPairs = ImmutableMap + .>builder() + // retryQueueSize + .put(join("retry.queue.size", "get size of retry queue."), TcpSummaryMetrics::getRetrySize) + // client2eventMeshTPS + .put(join("server.tps", "get tps of client to eventMesh."), TcpSummaryMetrics::getClient2eventMeshTPS) + // eventMesh2mqTPS + .put(join("mq.provider.tps", "get tps of eventMesh to mq."), TcpSummaryMetrics::getEventMesh2mqTPS) + // mq2eventMeshTPS + .put(join("mq.consumer.tps", "get tps of mq to eventMesh."), TcpSummaryMetrics::getMq2eventMeshTPS) + // eventMesh2clientTPS + .put(join("client.tps", "get tps of eventMesh to client."), TcpSummaryMetrics::getEventMesh2clientTPS) + // allTPS + .put(join("all.tps", "get all TPS."), TcpSummaryMetrics::getAllTPS) + // EventMeshTcpConnectionHandler.connections + .put(join("connection.num", "EventMeshTcpConnectionHandler.connections."), TcpSummaryMetrics::getAllConnections) + // subTopicNum + .put(join("sub.topic.num", "get sub topic num."), TcpSummaryMetrics::getSubTopicNum) + .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(); + public void export(final String meterName, final TcpSummaryMetrics summaryMetrics) { + final Meter meter = GlobalMeterProvider.getMeter(meterName); + paramPairs.forEach( + (metricInfo, getMetric) -> observeOfValue(meter, METRICS_TCP_PREFIX + metricInfo[0], metricInfo[1], + TCP, summaryMetrics, getMetric, TcpSummaryMetrics.class)); } } diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/utils/PrometheusExporterConstants.java b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/utils/PrometheusExporterConstants.java new file mode 100644 index 0000000000..9da69e2b7d --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/utils/PrometheusExporterConstants.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.metrics.prometheus.utils; + +/** + * Constants in metrics-prometheus module + */ +public class PrometheusExporterConstants { + + public static final String METRICS_GRPC_PREFIX = "eventmesh.grpc."; + + public static final String METRICS_TCP_PREFIX = "eventmesh.tcp."; + +} diff --git a/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/utils/PrometheusExporterUtils.java b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/utils/PrometheusExporterUtils.java new file mode 100644 index 0000000000..1a772020c3 --- /dev/null +++ b/eventmesh-metrics-plugin/eventmesh-metrics-prometheus/src/main/java/org/apache/eventmesh/metrics/prometheus/utils/PrometheusExporterUtils.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.metrics.prometheus.utils; + +import org.apache.eventmesh.metrics.api.model.Metric; + +import java.lang.reflect.Method; +import java.util.function.Function; + +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.metrics.common.Labels; + +import lombok.SneakyThrows; + +/** + * Utils for metrics-prometheus module + */ +public class PrometheusExporterUtils { + + /** + * Build the OpenTelemetry's Meter + * + * @param meter + * @param metricName + * @param metricDesc + * @param protocol + * @param summaryMetrics + * @param getMetric + */ + @SneakyThrows + public static void observeOfValue(Meter meter, String metricName, String metricDesc, String protocol, + Metric summaryMetrics, Function getMetric, Class clazz) { + Method method = getMetric.getClass().getMethod("apply", Object.class); + Class metricType = (Class) method.getGenericReturnType(); + if (metricType == Long.class) { + meter.longValueObserverBuilder(metricName) + .setDescription(metricDesc) + .setUnit(protocol) + .setUpdater(result -> result.observe((long) getMetric.apply(clazz.cast(summaryMetrics)), Labels.empty())) + .build(); + } else if (metricType == Double.class) { + meter.doubleValueObserverBuilder(metricName) + .setDescription(metricDesc) + .setUnit(protocol) + .setUpdater(result -> result.observe((double) getMetric.apply(clazz.cast(summaryMetrics)), Labels.empty())) + .build(); + } + } + + /** + * create and init an array contains 2 String. + * + * @param metricName the metric name + * @param desc the description of metric + * @return + */ + public static String[] join(String metricName, String desc) { + return new String[]{metricName, desc}; + } + +} 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 index 4ed07ea1f2..3a4227e3ae 100644 --- 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 @@ -20,8 +20,8 @@ import org.apache.eventmesh.metrics.api.MetricsPluginFactory; import org.apache.eventmesh.metrics.prometheus.PrometheusMetricsRegistry; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class PrometheusConfigurationTest { @@ -35,6 +35,6 @@ public void getConfigWhenPrometheusMetricsRegistryInit() { } private void assertConfig(PrometheusConfiguration config) { - Assert.assertEquals(config.getEventMeshPrometheusPort(), 19091); + Assertions.assertEquals(config.getEventMeshPrometheusPort(), 19091); } } diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/build.gradle b/eventmesh-openconnect/eventmesh-openconnect-java/build.gradle index 07db9fff9e..d47a81a4ff 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/build.gradle +++ b/eventmesh-openconnect/eventmesh-openconnect-java/build.gradle @@ -19,13 +19,15 @@ dependencies { api "org.slf4j:slf4j-api" implementation "org.apache.logging.log4j:log4j-api" implementation "org.apache.logging.log4j:log4j-core" - implementation "org.apache.logging.log4j:log4j-slf4j-impl" + implementation "org.apache.logging.log4j:log4j-slf4j2-impl" implementation "com.fasterxml.jackson.core:jackson-databind" implementation "com.fasterxml.jackson.core:jackson-core" implementation "com.fasterxml.jackson.core:jackson-annotations" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml" + api project (":eventmesh-openconnect:eventmesh-openconnect-offsetmgmt-plugin:eventmesh-openconnect-offsetmgmt-api") + implementation project (":eventmesh-openconnect:eventmesh-openconnect-offsetmgmt-plugin:eventmesh-openconnect-offsetmgmt-nacos") implementation project(":eventmesh-sdks:eventmesh-sdk-java") compileOnly 'org.projectlombok:lombok' diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/Application.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/Application.java index 7d9b298c81..3252a52e3e 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/Application.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/Application.java @@ -17,6 +17,7 @@ package org.apache.eventmesh.openconnect; +import org.apache.eventmesh.openconnect.api.ConnectorCreateService; import org.apache.eventmesh.openconnect.api.config.Config; import org.apache.eventmesh.openconnect.api.config.SinkConfig; import org.apache.eventmesh.openconnect.api.config.SourceConfig; @@ -24,16 +25,47 @@ import org.apache.eventmesh.openconnect.api.sink.Sink; import org.apache.eventmesh.openconnect.api.source.Source; import org.apache.eventmesh.openconnect.util.ConfigUtil; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import org.apache.commons.collections4.MapUtils; + +import java.util.HashMap; +import java.util.Map; import lombok.extern.slf4j.Slf4j; @Slf4j public class Application { - public static void run(Class clazz) throws Exception { - Connector connector; + public static final Map CONNECTOR_MAP = new HashMap<>(); + + public static final String CREATE_EXTENSION_KEY = "createExtension"; + + private Map extensions; + + public Application() { + + } + + public Application(Map extensions) { + this.extensions = extensions; + } + + public void run(Class clazz) throws Exception { + + Connector connector = null; try { - connector = clazz.getDeclaredConstructor().newInstance(); + if (MapUtils.isNotEmpty(extensions) && extensions.containsKey(CREATE_EXTENSION_KEY)) { + String spiKey = extensions.get(CREATE_EXTENSION_KEY); + ConnectorCreateService createService = + EventMeshExtensionFactory.getExtension(ConnectorCreateService.class, spiKey); + if (createService != null) { + connector = createService.create(); + } + } + if (connector == null) { + connector = clazz.getDeclaredConstructor().newInstance(); + } } catch (Exception e) { log.error("new connector error", e); return; @@ -41,18 +73,10 @@ public static void run(Class clazz) throws Exception { Config config; try { config = ConfigUtil.parse(connector.configClass()); - // offset storage, memory default - //KVStoreFactory.setStoreConfig(config.getStoreConfig()); } catch (Exception e) { log.error("parse config error", e); return; } - try { - connector.init(config); - } catch (Exception e) { - log.error("connector {} initialize error", connector.name(), e); - return; - } ConnectorWorker worker; if (isSink(clazz)) { @@ -63,15 +87,19 @@ public static void run(Class clazz) throws Exception { log.error("class {} is not sink and source", clazz); return; } + worker.init(); + + CONNECTOR_MAP.putIfAbsent(connector.name(), connector); + Connector finalConnector = connector; Runtime.getRuntime().addShutdownHook(new Thread(() -> { worker.stop(); - log.info("connector {} stopped", connector.name()); + log.info("connector {} stopped", finalConnector.name()); })); worker.start(); log.info("connector {} started", connector.name()); } - private static boolean isAssignableFrom(Class c, Class cls) { + public static boolean isAssignableFrom(Class c, Class cls) { Class[] clazzArr = c.getInterfaces(); for (Class clazz : clazzArr) { if (clazz.isAssignableFrom(cls)) { @@ -81,7 +109,7 @@ private static boolean isAssignableFrom(Class c, Class cls) { return false; } - private static boolean isSink(Class c) { + public static boolean isSink(Class c) { while (c != null && c != Object.class) { if (isAssignableFrom(c, Sink.class)) { return true; @@ -91,7 +119,7 @@ private static boolean isSink(Class c) { return false; } - private static boolean isSource(Class c) { + public static boolean isSource(Class c) { while (c != null && c != Object.class) { if (isAssignableFrom(c, Source.class)) { return true; diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/ConnectorWorker.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/ConnectorWorker.java index bf0d1dda84..908464711f 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/ConnectorWorker.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/ConnectorWorker.java @@ -22,6 +22,8 @@ */ public interface ConnectorWorker { + void init(); + /** * Starts the worker */ diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/SinkWorker.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/SinkWorker.java index 6cdaa629a0..a62b1b19ba 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/SinkWorker.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/SinkWorker.java @@ -27,12 +27,13 @@ import org.apache.eventmesh.common.protocol.tcp.UserAgent; import org.apache.eventmesh.common.utils.SystemUtils; import org.apache.eventmesh.openconnect.api.config.SinkConfig; -import org.apache.eventmesh.openconnect.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.api.connector.SinkConnectorContext; import org.apache.eventmesh.openconnect.api.sink.Sink; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.Optional; import io.cloudevents.CloudEvent; @@ -47,12 +48,10 @@ public class SinkWorker implements ConnectorWorker { private final EventMeshTCPClient eventMeshTCPClient; - public SinkWorker(Sink sink, SinkConfig config) throws Exception { + public SinkWorker(Sink sink, SinkConfig config) { this.sink = sink; this.config = config; - sink.init(config); eventMeshTCPClient = buildEventMeshSubClient(config); - eventMeshTCPClient.init(); } private EventMeshTCPClient buildEventMeshSubClient(SinkConfig config) { @@ -82,6 +81,18 @@ private EventMeshTCPClient buildEventMeshSubClient(SinkConfig config return EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); } + @Override + public void init() { + SinkConnectorContext sinkConnectorContext = new SinkConnectorContext(); + sinkConnectorContext.setSinkConfig(config); + try { + sink.init(sinkConnectorContext); + } catch (Exception e) { + throw new RuntimeException(e); + } + eventMeshTCPClient.init(); + } + @Override public void start() { log.info("sink worker starting {}", sink.name()); @@ -125,16 +136,7 @@ public EventHandler(Sink sink) { @Override public Optional handle(CloudEvent event) { - byte[] body = Objects.requireNonNull(event.getData()).toBytes(); - //todo: recordPartition & recordOffset - ConnectRecord connectRecord = new ConnectRecord(null, null, System.currentTimeMillis(), body); - for (String extensionName : event.getExtensionNames()) { - connectRecord.addExtension(extensionName, Objects.requireNonNull(event.getExtension(extensionName)).toString()); - } - connectRecord.addExtension("id", event.getId()); - connectRecord.addExtension("topic", event.getSubject()); - connectRecord.addExtension("source", event.getSource().toString()); - connectRecord.addExtension("type", event.getType()); + ConnectRecord connectRecord = CloudEventUtil.convertEventToRecord(event); List connectRecords = new ArrayList<>(); connectRecords.add(connectRecord); sink.put(connectRecords); diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/SourceWorker.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/SourceWorker.java index b479aa9829..c5d4fe2b07 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/SourceWorker.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/SourceWorker.java @@ -17,25 +17,49 @@ package org.apache.eventmesh.openconnect; +import static org.apache.eventmesh.common.Constants.CLOUD_EVENTS_PROTOCOL_NAME; + 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.common.MessageUtils; import org.apache.eventmesh.client.tcp.conf.EventMeshTCPClientConfig; +import org.apache.eventmesh.common.exception.EventMeshException; +import org.apache.eventmesh.common.protocol.tcp.Package; import org.apache.eventmesh.common.protocol.tcp.UserAgent; import org.apache.eventmesh.common.utils.JsonUtils; import org.apache.eventmesh.common.utils.SystemUtils; +import org.apache.eventmesh.openconnect.api.callback.SendExcepionContext; +import org.apache.eventmesh.openconnect.api.callback.SendMessageCallback; +import org.apache.eventmesh.openconnect.api.callback.SendResult; import org.apache.eventmesh.openconnect.api.config.SourceConfig; -import org.apache.eventmesh.openconnect.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.api.connector.SourceConnectorContext; import org.apache.eventmesh.openconnect.api.source.Source; +import org.apache.eventmesh.openconnect.offsetmgmt.api.config.OffsetStorageConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffsetManagement; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.DefaultOffsetManagementServiceImpl; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.OffsetManagementService; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.OffsetStorageReaderImpl; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.OffsetStorageWriterImpl; +import org.apache.eventmesh.openconnect.util.CloudEventUtil; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import org.apache.commons.collections4.CollectionUtils; import java.net.URI; import java.nio.charset.StandardCharsets; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.UUID; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import io.cloudevents.CloudEvent; import io.cloudevents.core.builder.CloudEventBuilder; @@ -48,16 +72,34 @@ public class SourceWorker implements ConnectorWorker { private final Source source; private final SourceConfig config; + private static final int MAX_RETRY_TIMES = 3; + + public static final String CALLBACK_EXTENSION = "callBackExtension"; + + private OffsetStorageWriterImpl offsetStorageWriter; + + private OffsetStorageReaderImpl offsetStorageReader; + + private OffsetManagementService offsetManagementService; + + private RecordOffsetManagement offsetManagement; + + private volatile RecordOffsetManagement.CommittableOffsets committableOffsets; + + private final ExecutorService pollService = Executors.newSingleThreadExecutor(); + + private final ExecutorService startService = Executors.newSingleThreadExecutor(); + + private final BlockingQueue queue; private final EventMeshTCPClient eventMeshTCPClient; - private volatile boolean isRunning = true; + private volatile boolean isRunning = false; - public SourceWorker(Source source, SourceConfig config) throws Exception { + public SourceWorker(Source source, SourceConfig config) { this.source = source; this.config = config; - source.init(config); + queue = new LinkedBlockingQueue<>(1000); eventMeshTCPClient = buildEventMeshPubClient(config); - eventMeshTCPClient.init(); } private EventMeshTCPClient buildEventMeshPubClient(SourceConfig config) { @@ -87,39 +129,144 @@ private EventMeshTCPClient buildEventMeshPubClient(SourceConfig conf return EventMeshTCPClientFactory.createEventMeshTCPClient(eventMeshTcpClientConfig, CloudEvent.class); } + @Override + public void init() { + SourceConnectorContext sourceConnectorContext = new SourceConnectorContext(); + sourceConnectorContext.setSourceConfig(config); + sourceConnectorContext.setOffsetStorageReader(offsetStorageReader); + try { + source.init(sourceConnectorContext); + } catch (Exception e) { + throw new RuntimeException(e); + } + eventMeshTCPClient.init(); + // spi load offsetMgmtService + this.offsetManagement = new RecordOffsetManagement(); + this.committableOffsets = RecordOffsetManagement.CommittableOffsets.EMPTY; + OffsetStorageConfig offsetStorageConfig = config.getOffsetStorageConfig(); + this.offsetManagementService = Optional.ofNullable(offsetStorageConfig) + .map(OffsetStorageConfig::getOffsetStorageType) + .map(storageType -> EventMeshExtensionFactory.getExtension(OffsetManagementService.class, storageType)) + .orElse(new DefaultOffsetManagementServiceImpl()); + this.offsetManagementService.initialize(offsetStorageConfig); + this.offsetStorageWriter = new OffsetStorageWriterImpl(source.name(), offsetManagementService); + this.offsetStorageReader = new OffsetStorageReaderImpl(source.name(), offsetManagementService); + } + @Override public void start() { log.info("source worker starting {}", source.name()); log.info("event mesh address is {}", config.getPubSubConfig().getMeshAddress()); - try { - source.start(); - while (isRunning) { - List connectorRecordList = source.poll(); - for (ConnectRecord connectRecord : connectorRecordList) { - // todo: convert connectRecord to cloudevent - CloudEvent event = convertRecordToEvent(connectRecord); - eventMeshTCPClient.publish(event, 3000); + // start offsetMgmtService + offsetManagementService.start(); + isRunning = true; + pollService.execute(this::startPollAndSend); + + startService.execute( + () -> { + try { + startConnector(); + } catch (Exception e) { + log.error("source worker[{}] start fail", source.name(), e); + this.stop(); } + }); + } + + public void startPollAndSend() { + while (isRunning) { + ConnectRecord connectRecord = null; + try { + connectRecord = queue.poll(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("poll connect record error", e); + } + if (connectRecord == null) { + continue; + } + // todo: convert connectRecord to cloudevent + CloudEvent event = convertRecordToEvent(connectRecord); + Optional submittedRecordPosition = prepareToUpdateRecordOffset(connectRecord); + Optional callback = Optional.ofNullable(connectRecord.getExtensionObj(CALLBACK_EXTENSION)) + .map(v -> (SendMessageCallback) v); + + int retryTimes = 0; + // retry until MAX_RETRY_TIMES is reached + while (retryTimes < MAX_RETRY_TIMES) { + try { + Package sendResult = eventMeshTCPClient.publish(event, 3000); + if (sendResult.getHeader().getCode() == 0) { + // publish success + // commit record + this.source.commit(connectRecord); + submittedRecordPosition.ifPresent(RecordOffsetManagement.SubmittedPosition::ack); + callback.ifPresent(cb -> cb.onSuccess(convertToSendResult(event))); + break; + } + throw new EventMeshException("failed to send record."); + } catch (Throwable t) { + retryTimes++; + log.error("{} failed to send record to {}, retry times = {}, failed record {}, throw {}", + this, event.getSubject(), retryTimes, connectRecord, t.getMessage()); + callback.ifPresent(cb -> cb.onException(convertToExceptionContext(event, t))); + } + } + + offsetManagement.awaitAllMessages(5000, TimeUnit.MILLISECONDS); + // update & commit offset + updateCommittableOffsets(); + commitOffsets(); + } + } + + private void startConnector() throws Exception { + source.start(); + while (isRunning) { + List connectorRecordList = source.poll(); + if (CollectionUtils.isEmpty(connectorRecordList)) { + continue; + } + for (ConnectRecord record : connectorRecordList) { + queue.put(record); } - log.info("source worker[{}] started", source.name()); - } catch (Exception e) { - log.error("source worker[{}] start fail", source.name(), e); } } private CloudEvent convertRecordToEvent(ConnectRecord connectRecord) { - final Map content = new HashMap<>(); - content.put("content", connectRecord.getData().toString()); + CloudEventBuilder cloudEventBuilder = CloudEventBuilder.v1(); - return CloudEventBuilder.v1() - .withId(UUID.randomUUID().toString()) + cloudEventBuilder.withId(UUID.randomUUID().toString()) .withSubject(config.getPubSubConfig().getSubject()) .withSource(URI.create("/")) .withDataContentType("application/cloudevents+json") - .withType(EventMeshCommon.CLOUD_EVENTS_PROTOCOL_NAME) - .withData(Objects.requireNonNull(JsonUtils.toJSONString(content)).getBytes(StandardCharsets.UTF_8)) - .withExtension("ttl", 10000) - .build(); + .withType(CLOUD_EVENTS_PROTOCOL_NAME) + .withData(Objects.requireNonNull(JsonUtils.toJSONString(connectRecord.getData())).getBytes(StandardCharsets.UTF_8)) + .withExtension("ttl", 10000); + + if (connectRecord.getExtensions() != null) { + for (String key : connectRecord.getExtensions().keySet()) { + if (CloudEventUtil.validateExtensionType(connectRecord.getExtensionObj(key))) { + cloudEventBuilder.withExtension(key, connectRecord.getExtension(key)); + } + } + } + return cloudEventBuilder.build(); + } + + private SendResult convertToSendResult(CloudEvent event) { + SendResult result = new SendResult(); + result.setMessageId(event.getId()); + result.setTopic(event.getSubject()); + return result; + } + + private SendExcepionContext convertToExceptionContext(CloudEvent event, Throwable cause) { + SendExcepionContext exceptionContext = new SendExcepionContext(); + exceptionContext.setTopic(event.getId()); + exceptionContext.setMessageId(event.getId()); + exceptionContext.setCause(cause); + return exceptionContext; } @Override @@ -129,17 +276,97 @@ public void stop() { try { source.stop(); } catch (Exception e) { - e.printStackTrace(); log.error("source destroy error", e); } + log.info("pollService stopping"); + pollService.shutdown(); + try { + pollService.awaitTermination(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + log.error("awaitTermination error", e); + } + log.info("offsetMgmtService stopping"); + offsetManagementService.stop(); try { + log.info("eventmesh client closing"); eventMeshTCPClient.close(); } catch (Exception e) { - e.printStackTrace(); - log.error("event mesh client close", e); + log.error("event mesh client close error", e); } log.info("source worker stopped"); } + public Optional prepareToUpdateRecordOffset(ConnectRecord record) { + return Optional.of(this.offsetManagement.submitRecord(record.getPosition())); + } + + public void updateCommittableOffsets() { + RecordOffsetManagement.CommittableOffsets newOffsets = offsetManagement.committableOffsets(); + synchronized (this) { + this.committableOffsets = this.committableOffsets.updatedWith(newOffsets); + } + } + + public boolean commitOffsets() { + log.info("Start Committing offsets"); + + long timeout = System.currentTimeMillis() + 5000L; + + RecordOffsetManagement.CommittableOffsets offsetsToCommit; + synchronized (this) { + offsetsToCommit = this.committableOffsets; + this.committableOffsets = RecordOffsetManagement.CommittableOffsets.EMPTY; + } + + if (committableOffsets.isEmpty()) { + log.debug("Either no records were produced since the last offset commit, " + + "or every record has been filtered out by a transformation " + + "or dropped due to transformation or conversion errors."); + // We continue with the offset commit process here instead of simply returning immediately + // in order to invoke SourceTask::commit and record metrics for a successful offset commit + } else { + log.info("{} Committing offsets for {} acknowledged messages", this, committableOffsets.numCommittableMessages()); + if (committableOffsets.hasPending()) { + log.debug("{} There are currently {} pending messages spread across {} source partitions whose offsets will not be committed. " + + "The source partition with the most pending messages is {}, with {} pending messages", + this, + committableOffsets.numUncommittableMessages(), + committableOffsets.numDeques(), + committableOffsets.largestDequePartition(), + committableOffsets.largestDequeSize()); + } else { + log.debug("{} There are currently no pending messages for this offset commit; " + + "all messages dispatched to the task's producer since the last commit have been acknowledged", + this); + } + } + + // write offset to memory + offsetsToCommit.offsets().forEach(offsetStorageWriter::writeOffset); + + // begin flush + if (!offsetStorageWriter.beginFlush()) { + return true; + } + + // using offsetManagementService to persist offset + Future flushFuture = offsetStorageWriter.doFlush(); + try { + flushFuture.get(Math.max(timeout - System.currentTimeMillis(), 0), TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + log.warn("{} Flush of offsets interrupted, cancelling", this); + offsetStorageWriter.cancelFlush(); + return false; + } catch (ExecutionException e) { + log.error("{} Flush of offsets threw an unexpected exception: ", this, e); + offsetStorageWriter.cancelFlush(); + return false; + } catch (TimeoutException e) { + log.error("{} Timed out waiting to flush offsets to storage; will try again on next flush interval with latest offsets", this); + offsetStorageWriter.cancelFlush(); + return false; + } + return true; + } } diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/ConnectorCreateService.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/ConnectorCreateService.java new file mode 100644 index 0000000000..15e645474c --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/ConnectorCreateService.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.openconnect.api; + +import org.apache.eventmesh.openconnect.api.connector.Connector; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +/** + * SPI interface for connector creation. + */ +@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.CONNECTOR) +public interface ConnectorCreateService { + + T create(); +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/callback/SendExcepionContext.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/callback/SendExcepionContext.java new file mode 100644 index 0000000000..0311ceaef5 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/callback/SendExcepionContext.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.openconnect.api.callback; + +public class SendExcepionContext { + + private String messageId; + private String topic; + private Throwable cause; + + public SendExcepionContext() { + } + + public String getMessageId() { + return this.messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getTopic() { + return this.topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public Throwable getCause() { + return this.cause; + } + + public void setCause(Throwable cause) { + this.cause = cause; + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/callback/SendMessageCallback.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/callback/SendMessageCallback.java new file mode 100644 index 0000000000..fd6baba7ec --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/callback/SendMessageCallback.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.openconnect.api.callback; + +/** + * Message sending callback interface. + */ +public interface SendMessageCallback { + + void onSuccess(SendResult sendResult); + + void onException(SendExcepionContext sendExcepionContext); +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/callback/SendResult.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/callback/SendResult.java new file mode 100644 index 0000000000..8cd861f6de --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/callback/SendResult.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.openconnect.api.callback; + +public class SendResult { + + private String messageId; + private String topic; + + public SendResult() { + } + + public String getMessageId() { + return this.messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + public String getTopic() { + return this.topic; + } + + public void setTopic(String topic) { + this.topic = topic; + } + + public String toString() { + return "SendResult[topic=" + this.topic + ", messageId=" + this.messageId + ']'; + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/Constants.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/Constants.java index de8eb51a53..59794e562a 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/Constants.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/Constants.java @@ -23,7 +23,9 @@ public class Constants { public static final String ENV_PORT = "connectorPort"; - public static final String ENV_CONFIG_FILE = "connectorConf"; + public static final String ENV_SOURCE_CONFIG_FILE = "sourceConnectorConf"; + + public static final String ENV_SINK_CONFIG_FILE = "sinkConnectorConf"; public static final int DEFAULT_ATTEMPT = 3; diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/SinkConfig.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/SinkConfig.java index 7a7e997a57..527d02e04d 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/SinkConfig.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/SinkConfig.java @@ -18,8 +18,10 @@ package org.apache.eventmesh.openconnect.api.config; import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = true) public abstract class SinkConfig extends Config { private PubSubConfig pubSubConfig; diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/SourceConfig.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/SourceConfig.java index d18ac4c6d4..2942be936c 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/SourceConfig.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/config/SourceConfig.java @@ -17,11 +17,17 @@ package org.apache.eventmesh.openconnect.api.config; +import org.apache.eventmesh.openconnect.offsetmgmt.api.config.OffsetStorageConfig; + import lombok.Data; +import lombok.EqualsAndHashCode; @Data +@EqualsAndHashCode(callSuper = true) public abstract class SourceConfig extends Config { private PubSubConfig pubSubConfig; + private OffsetStorageConfig offsetStorageConfig; + } diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/Connector.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/Connector.java index 3ea43575b4..82993b198b 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/Connector.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/Connector.java @@ -18,7 +18,7 @@ package org.apache.eventmesh.openconnect.api.connector; import org.apache.eventmesh.openconnect.api.config.Config; -import org.apache.eventmesh.openconnect.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; /** * Connector @@ -33,13 +33,25 @@ public interface Connector { Class configClass(); /** + * This init method is obsolete. For detailed discussion, + * please see here + *

* Initializes the Connector with the provided configuration. * * @param config Configuration object * @throws Exception if initialization fails */ + @Deprecated void init(Config config) throws Exception; + /** + * Initializes the Connector with the provided context. + * + * @param connectorContext connectorContext + * @throws Exception if initialization fails + */ + void init(ConnectorContext connectorContext) throws Exception; + /** * Starts the Connector. * diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/ConnectorContext.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/ConnectorContext.java new file mode 100644 index 0000000000..bc4298fde5 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/ConnectorContext.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.openconnect.api.connector; + +/** + * Connector Context + */ +public interface ConnectorContext { + +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/SinkConnectorContext.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/SinkConnectorContext.java new file mode 100644 index 0000000000..a7aef4fff2 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/SinkConnectorContext.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.openconnect.api.connector; + +import org.apache.eventmesh.openconnect.api.config.SinkConfig; + +import lombok.Data; + +/** + * Sink Connector Context + */ +@Data +public class SinkConnectorContext implements ConnectorContext { + + public SinkConfig sinkConfig; + +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/SourceConnectorContext.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/SourceConnectorContext.java new file mode 100644 index 0000000000..14fd92218a --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/connector/SourceConnectorContext.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.openconnect.api.connector; + +import org.apache.eventmesh.openconnect.api.config.SourceConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.OffsetStorageReader; + +import lombok.Data; + +/** + * Source Connector Context + */ +@Data +public class SourceConnectorContext implements ConnectorContext { + + public OffsetStorageReader offsetStorageReader; + + public SourceConfig sourceConfig; + +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/DefaultKeyValue.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/DefaultKeyValue.java deleted file mode 100644 index 6ce1b551f9..0000000000 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/DefaultKeyValue.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.openconnect.api.data; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -public class DefaultKeyValue implements KeyValue { - - private Map properties = new ConcurrentHashMap<>(); - - @Override - public boolean getBoolean(String key) { - if (!properties.containsKey(key)) { - return false; - } - return Boolean.parseBoolean(properties.get(key)); - } - - @Override - public boolean getBoolean(String key, boolean defaultValue) { - return properties.containsKey(key) ? getBoolean(key) : defaultValue; - } - - @Override - public short getShort(String key) { - if (!properties.containsKey(key)) { - return 0; - } - return Short.parseShort(properties.get(key)); - } - - @Override - public short getShort(String key, short defaultValue) { - return properties.containsKey(key) ? getShort(key) : defaultValue; - } - - @Override - public KeyValue put(String key, boolean value) { - properties.put(key, String.valueOf(value)); - return this; - } - - @Override - public KeyValue put(String key, short value) { - properties.put(key, String.valueOf(value)); - return this; - } - - public DefaultKeyValue() { - properties = new ConcurrentHashMap(); - } - - @Override - public KeyValue put(String key, int value) { - properties.put(key, String.valueOf(value)); - return this; - } - - @Override - public KeyValue put(String key, long value) { - properties.put(key, String.valueOf(value)); - return this; - } - - @Override - public KeyValue put(String key, double value) { - properties.put(key, String.valueOf(value)); - return this; - } - - @Override - public KeyValue put(String key, String value) { - properties.put(key, String.valueOf(value)); - return this; - } - - @Override - public int getInt(String key) { - if (!properties.containsKey(key)) { - return 0; - } - return Integer.parseInt(properties.get(key)); - } - - @Override - public int getInt(final String key, final int defaultValue) { - return properties.containsKey(key) ? getInt(key) : defaultValue; - } - - @Override - public long getLong(String key) { - if (!properties.containsKey(key)) { - return 0; - } - return Long.parseLong(properties.get(key)); - } - - @Override - public long getLong(final String key, final long defaultValue) { - return properties.containsKey(key) ? getLong(key) : defaultValue; - } - - @Override - public double getDouble(String key) { - if (!properties.containsKey(key)) { - return 0; - } - return Double.parseDouble(properties.get(key)); - } - - @Override - public double getDouble(final String key, final double defaultValue) { - return properties.containsKey(key) ? getDouble(key) : defaultValue; - } - - @Override - public String getString(String key) { - return properties.get(key); - } - - @Override - public String getString(final String key, final String defaultValue) { - return properties.containsKey(key) ? getString(key) : defaultValue; - } - - @Override - public Set keySet() { - return properties.keySet(); - } - - @Override - public boolean containsKey(String key) { - return properties.containsKey(key); - } -} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/KeyValue.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/KeyValue.java deleted file mode 100644 index ecd374dd1c..0000000000 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/KeyValue.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.openconnect.api.data; - -import java.util.Set; - -/** - * used for connector-record extension - */ -public interface KeyValue { - - KeyValue put(String key, boolean value); - - KeyValue put(String key, short value); - - KeyValue put(String key, int value); - - KeyValue put(String key, long value); - - KeyValue put(String key, double value); - - KeyValue put(String key, String value); - - boolean getBoolean(String key); - - boolean getBoolean(String key, boolean defaultValue); - - short getShort(String key); - - short getShort(String key, short defaultValue); - - int getInt(String key); - - int getInt(String key, int defaultValue); - - long getLong(String key); - - long getLong(String key, long defaultValue); - - double getDouble(String key); - - double getDouble(String key, double defaultValue); - - String getString(String key); - - String getString(String key, String defaultValue); - - Set keySet(); - - boolean containsKey(String key); -} \ No newline at end of file diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/sink/Sink.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/sink/Sink.java index 1982c4fa76..bcacd1ebae 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/sink/Sink.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/sink/Sink.java @@ -18,7 +18,7 @@ package org.apache.eventmesh.openconnect.api.sink; import org.apache.eventmesh.openconnect.api.connector.Connector; -import org.apache.eventmesh.openconnect.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; import java.util.List; diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/Source.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/Source.java index 1b2b849b5e..d2b35a931d 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/Source.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/source/Source.java @@ -18,7 +18,7 @@ package org.apache.eventmesh.openconnect.api.source; import org.apache.eventmesh.openconnect.api.connector.Connector; -import org.apache.eventmesh.openconnect.api.data.ConnectRecord; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; import java.util.List; diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/util/CloudEventUtil.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/util/CloudEventUtil.java new file mode 100644 index 0000000000..5d4a77ff78 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/util/CloudEventUtil.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.openconnect.util; + +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.utils.LogUtil; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.ConnectRecord; + +import java.net.URI; +import java.net.URISyntaxException; +import java.time.OffsetDateTime; +import java.util.Objects; +import java.util.Optional; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class CloudEventUtil { + + public static CloudEvent convertRecordToEvent(ConnectRecord connectRecord) { + final CloudEventBuilder cloudEventBuilder = CloudEventBuilder.v1().withData((byte[]) connectRecord.getData()); + Optional.ofNullable(connectRecord.getExtensions()).ifPresent((extensions) -> extensions.keySet().forEach(key -> { + switch (key) { + case "id": + cloudEventBuilder.withId(connectRecord.getExtension(key)); + break; + case "topic": + cloudEventBuilder.withSubject(connectRecord.getExtension(key)); + break; + case "source": + try { + cloudEventBuilder.withSource(new URI(connectRecord.getExtension(key))); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + break; + case "type": + cloudEventBuilder.withType(connectRecord.getExtension(key)); + break; + default: + if (validateExtensionType(connectRecord.getExtensionObj(key))) { + cloudEventBuilder.withExtension(key, connectRecord.getExtension(key)); + } + } + })); + return cloudEventBuilder.build(); + } + + public static ConnectRecord convertEventToRecord(CloudEvent event) { + byte[] body = Objects.requireNonNull(event.getData()).toBytes(); + LogUtil.info(log, "handle receive events {}", () -> new String(event.getData().toBytes(), Constants.DEFAULT_CHARSET)); + // todo: recordPartition & recordOffset + ConnectRecord connectRecord = new ConnectRecord(null, null, System.currentTimeMillis(), body); + for (String extensionName : event.getExtensionNames()) { + connectRecord.addExtension(extensionName, Objects.requireNonNull(event.getExtension(extensionName)).toString()); + } + connectRecord.addExtension("id", event.getId()); + connectRecord.addExtension("topic", event.getSubject()); + connectRecord.addExtension("source", event.getSource().toString()); + connectRecord.addExtension("type", event.getType()); + connectRecord.addExtension("datacontenttype", event.getDataContentType()); + return connectRecord; + } + + public static boolean validateExtensionType(Object obj) { + return obj instanceof String || obj instanceof Number || obj instanceof Boolean + || obj instanceof URI || obj instanceof OffsetDateTime || obj instanceof byte[]; + } + +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/util/ConfigUtil.java b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/util/ConfigUtil.java index fdd9df65cd..93b2ba9582 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/util/ConfigUtil.java +++ b/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/util/ConfigUtil.java @@ -19,6 +19,8 @@ import org.apache.eventmesh.openconnect.api.config.Config; import org.apache.eventmesh.openconnect.api.config.Constants; +import org.apache.eventmesh.openconnect.api.config.SinkConfig; +import org.apache.eventmesh.openconnect.api.config.SourceConfig; import java.io.File; import java.io.FileNotFoundException; @@ -37,10 +39,16 @@ public static Config parse(Class c) throws Exception { if (c == null) { return null; } - return parseConfig(c); + if (isSourceConfig(c)) { + return parseSourceConfig(c); + } else if (isSinkConfig(c)) { + return parseSinkConfig(c); + } else { + throw new RuntimeException("illegal config, parse config error"); + } } - private static T parse(Class c, String filePathName) throws Exception { + public static T parse(Class c, String filePathName) throws Exception { ObjectMapper objectMapper; if (filePathName.endsWith("json")) { objectMapper = new ObjectMapper(); @@ -59,11 +67,33 @@ private static T parse(Class c, String filePathName) throws Exception { return objectMapper.readValue(url, c); } - private static Config parseConfig(Class c) throws Exception { - String configFile = System.getProperty(Constants.ENV_CONFIG_FILE, System.getenv(Constants.ENV_CONFIG_FILE)); + private static Config parseSourceConfig(Class c) throws Exception { + String configFile = System.getProperty(Constants.ENV_SOURCE_CONFIG_FILE, System.getenv(Constants.ENV_SOURCE_CONFIG_FILE)); + if (configFile == null || configFile.isEmpty()) { + configFile = "source-config.yml"; + } + return parse(c, configFile); + } + + private static Config parseSinkConfig(Class c) throws Exception { + String configFile = System.getProperty(Constants.ENV_SINK_CONFIG_FILE, System.getenv(Constants.ENV_SINK_CONFIG_FILE)); if (configFile == null || configFile.isEmpty()) { - configFile = "config.yml"; + configFile = "sink-config.yml"; } return parse(c, configFile); } + + public static boolean isSinkConfig(Class c) { + if (c != null && c != Object.class) { + return SinkConfig.class.isAssignableFrom(c); + } + return false; + } + + public static boolean isSourceConfig(Class c) { + if (c != null && c != Object.class) { + return SourceConfig.class.isAssignableFrom(c); + } + return false; + } } diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/build.gradle b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/build.gradle new file mode 100644 index 0000000000..3f5f0a240b --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/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 "org.slf4j:slf4j-api" + implementation "org.apache.logging.log4j:log4j-api" + implementation "org.apache.logging.log4j:log4j-core" + implementation "org.apache.logging.log4j:log4j-slf4j2-impl" + + implementation "com.fasterxml.jackson.core:jackson-databind" + implementation "com.fasterxml.jackson.core:jackson-core" + implementation "com.fasterxml.jackson.core:jackson-annotations" + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml" + + implementation project(":eventmesh-sdks:eventmesh-sdk-java") + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} \ No newline at end of file diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/build.gradle b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/build.gradle new file mode 100644 index 0000000000..c5ac62b00f --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-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") + api "org.slf4j:slf4j-api" + implementation "org.apache.logging.log4j:log4j-api" + implementation "org.apache.logging.log4j:log4j-core" + implementation "org.apache.logging.log4j:log4j-slf4j2-impl" + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' + + testImplementation "org.mockito:mockito-core" +} diff --git a/eventmesh-admin/gradle.properties b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/gradle.properties similarity index 100% rename from eventmesh-admin/gradle.properties rename to eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/gradle.properties diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/config/OffsetStorageConfig.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/config/OffsetStorageConfig.java new file mode 100644 index 0000000000..30a56a3d2f --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/config/OffsetStorageConfig.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.openconnect.offsetmgmt.api.config; + +import java.util.Map; + +import lombok.Data; + +@Data +public class OffsetStorageConfig { + + private String offsetStorageType; + + private String offsetStorageAddr; + + private Map extensions; +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/ConnectRecord.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/ConnectRecord.java similarity index 86% rename from eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/ConnectRecord.java rename to eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/ConnectRecord.java index e33aa2a581..119f058b58 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/ConnectRecord.java +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/ConnectRecord.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.openconnect.api.data; +package org.apache.eventmesh.openconnect.offsetmgmt.api.data; import java.util.Objects; import java.util.Set; @@ -45,7 +45,6 @@ public ConnectRecord(RecordPartition recordPartition, RecordOffset recordOffset, this.data = data; } - public Long getTimestamp() { return timestamp; } @@ -84,11 +83,11 @@ public void addExtension(KeyValue extensions) { } Set keySet = extensions.keySet(); for (String key : keySet) { - this.extensions.put(key, extensions.getString(key)); + this.extensions.put(key, extensions.getObject(key)); } } - public void addExtension(String key, String value) { + public void addExtension(String key, Object value) { if (this.extensions == null) { this.extensions = new DefaultKeyValue(); } @@ -96,12 +95,26 @@ public void addExtension(String key, String value) { } public String getExtension(String key) { - if (this.extensions == null) { + if (this.extensions == null || !extensions.containsKey(key)) { return null; } return this.extensions.getString(key); } + public T getExtension(String key, Class c) { + if (this.extensions == null) { + return null; + } + return this.extensions.getObject(key, c); + } + + public Object getExtensionObj(String key) { + if (this.extensions == null) { + return null; + } + return this.extensions.getObject(key); + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/DefaultKeyValue.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/DefaultKeyValue.java new file mode 100644 index 0000000000..a0390c1892 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/DefaultKeyValue.java @@ -0,0 +1,302 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.openconnect.offsetmgmt.api.data; + +import java.net.URI; +import java.time.OffsetDateTime; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class DefaultKeyValue implements KeyValue { + + private final Map properties; + + public DefaultKeyValue() { + properties = new ConcurrentHashMap<>(); + } + + @Override + public KeyValue put(String key, Boolean value) { + properties.put(key, value); + return this; + } + + @Override + public KeyValue put(String key, Number value) { + properties.put(key, value); + return this; + + } + + @Override + public KeyValue put(String key, byte[] value) { + properties.put(key, value); + return this; + } + + @Override + public KeyValue put(String key, String value) { + properties.put(key, value); + return this; + } + + @Override + public KeyValue put(String key, URI value) { + properties.put(key, value); + return this; + } + + @Override + public KeyValue put(String key, OffsetDateTime value) { + properties.put(key, value); + return this; + } + + @Override + public KeyValue put(String key, Object value) { + properties.put(key, value); + return this; + } + + @Override + public boolean getBoolean(String key) { + if (!properties.containsKey(key)) { + return false; + } + Object val = properties.get(key); + if (val instanceof Boolean) { + return (Boolean) val; + } + return false; + } + + @Override + public boolean getBoolean(String key, boolean defaultValue) { + return properties.containsKey(key) ? getBoolean(key) : defaultValue; + } + + @Override + public byte getByte(String key) { + if (!properties.containsKey(key)) { + return 0; + } + Object val = properties.get(key); + if (val instanceof Byte) { + return (Byte) val; + } + return 0; + } + + @Override + public byte getByte(String key, byte defaultValue) { + return properties.containsKey(key) ? getByte(key) : defaultValue; + + } + + @Override + public short getShort(String key) { + if (!properties.containsKey(key)) { + return 0; + } + Object val = properties.get(key); + if (val instanceof Short) { + return (Short) val; + } + return 0; + } + + @Override + public short getShort(String key, short defaultValue) { + return properties.containsKey(key) ? getShort(key) : defaultValue; + } + + @Override + public int getInt(String key) { + if (!properties.containsKey(key)) { + return 0; + } + Object val = properties.get(key); + if (val instanceof Integer) { + return (Integer) val; + } + return 0; + } + + @Override + public int getInt(final String key, final int defaultValue) { + return properties.containsKey(key) ? getInt(key) : defaultValue; + } + + @Override + public long getLong(String key) { + if (!properties.containsKey(key)) { + return 0; + } + Object val = properties.get(key); + if (val instanceof Long) { + return (Long) val; + } + return 0; + } + + @Override + public long getLong(final String key, final long defaultValue) { + return properties.containsKey(key) ? getLong(key) : defaultValue; + } + + @Override + public float getFloat(String key) { + if (!properties.containsKey(key)) { + return 0; + } + Object val = properties.get(key); + if (val instanceof Float) { + return (Float) val; + } + return 0; + } + + @Override + public float getFloat(String key, float defaultValue) { + return properties.containsKey(key) ? getFloat(key) : defaultValue; + } + + @Override + public double getDouble(String key) { + if (!properties.containsKey(key)) { + return 0; + } + Object val = properties.get(key); + if (val instanceof Double) { + return (Double) val; + } + return 0; + } + + @Override + public double getDouble(final String key, final double defaultValue) { + return properties.containsKey(key) ? getDouble(key) : defaultValue; + } + + @Override + public byte[] getBytes(String key) { + if (!properties.containsKey(key)) { + return new byte[]{}; + } + Object val = properties.get(key); + if (val instanceof byte[]) { + return (byte[]) val; + } + return new byte[]{}; + } + + @Override + public byte[] getBytes(String key, byte[] defaultValue) { + return properties.containsKey(key) ? getBytes(key) : defaultValue; + } + + @Override + public String getString(String key) { + if (!properties.containsKey(key)) { + return ""; + } + Object val = properties.get(key); + if (val instanceof String) { + return (String) val; + } + return ""; + } + + @Override + public String getString(final String key, final String defaultValue) { + return properties.containsKey(key) ? getString(key) : defaultValue; + } + + @Override + public URI getURI(String key) { + if (!properties.containsKey(key)) { + return null; + } + Object val = properties.get(key); + if (val instanceof URI) { + return (URI) val; + } + return null; + } + + @Override + public URI getURI(String key, URI defaultValue) { + return properties.containsKey(key) ? getURI(key) : defaultValue; + } + + @Override + public OffsetDateTime getOffsetDateTime(String key) { + if (!properties.containsKey(key)) { + return null; + } + Object val = properties.get(key); + if (val instanceof OffsetDateTime) { + return (OffsetDateTime) val; + } + return null; + } + + @Override + public OffsetDateTime getOffsetDateTime(String key, OffsetDateTime defaultValue) { + return properties.containsKey(key) ? getOffsetDateTime(key) : defaultValue; + } + + @Override + public Object getObject(String key) { + return properties.getOrDefault(key, null); + } + + @Override + public Object getObject(String key, Object defaultValue) { + return properties.getOrDefault(key, defaultValue); + } + + @SuppressWarnings("unchecked") + @Override + public T getObject(String key, Class c) { + if (!properties.containsKey(key)) { + return null; + } + Object val = properties.get(key); + if (val.getClass() == c) { + return (T) val; + } + return null; + } + + @Override + public T getObject(String key, T defaultValue, Class c) { + return properties.containsKey(key) ? getObject(key, c) : defaultValue; + } + + @Override + public Set keySet() { + return properties.keySet(); + } + + @Override + public boolean containsKey(String key) { + return properties.containsKey(key); + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/KeyValue.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/KeyValue.java new file mode 100644 index 0000000000..1cff3ddfc7 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/KeyValue.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.openconnect.offsetmgmt.api.data; + +import java.net.URI; +import java.time.OffsetDateTime; +import java.util.Set; + +/** + * used for connector-record extension + */ +public interface KeyValue { + + KeyValue put(String key, Boolean value); + + KeyValue put(String key, Number value); + + KeyValue put(String key, byte[] value); + + KeyValue put(String key, String value); + + KeyValue put(String key, URI value); + + KeyValue put(String key, OffsetDateTime value); + + KeyValue put(String key, Object value); + + boolean getBoolean(String key); + + boolean getBoolean(String key, boolean defaultValue); + + byte getByte(String key); + + byte getByte(String key, byte defaultValue); + + short getShort(String key); + + short getShort(String key, short defaultValue); + + int getInt(String key); + + int getInt(String key, int defaultValue); + + long getLong(String key); + + long getLong(String key, long defaultValue); + + float getFloat(String key); + + float getFloat(String key, float defaultValue); + + double getDouble(String key); + + double getDouble(String key, double defaultValue); + + byte[] getBytes(String key); + + byte[] getBytes(String key, byte[] defaultValue); + + String getString(String key); + + String getString(String key, String defaultValue); + + URI getURI(String key); + + URI getURI(String key, URI defaultValue); + + OffsetDateTime getOffsetDateTime(String key); + + OffsetDateTime getOffsetDateTime(String key, OffsetDateTime defaultValue); + + Object getObject(String key); + + Object getObject(String key, Object defaultValue); + + T getObject(String key, Class c); + + T getObject(String key, T defaultValue, Class c); + + Set keySet(); + + boolean containsKey(String key); +} \ No newline at end of file diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/RecordOffset.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordOffset.java similarity index 87% rename from eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/RecordOffset.java rename to eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordOffset.java index 5be9b60a76..fee70de27e 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/RecordOffset.java +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordOffset.java @@ -15,8 +15,9 @@ * limitations under the License. */ -package org.apache.eventmesh.openconnect.api.data; +package org.apache.eventmesh.openconnect.offsetmgmt.api.data; +import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -26,7 +27,11 @@ public class RecordOffset { * if pull message from mq key=queueOffset, * value=queueOffset value */ - private final Map offset; + private Map offset = new HashMap<>(); + + public RecordOffset() { + + } public RecordOffset(Map offset) { this.offset = offset; @@ -53,10 +58,4 @@ public int hashCode() { return Objects.hash(offset); } - @Override - public String toString() { - return "RecordOffset{" - + "offset=" + offset - + "}"; - } } diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordOffsetManagement.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordOffsetManagement.java new file mode 100644 index 0000000000..2eaefbef29 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordOffsetManagement.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.openconnect.offsetmgmt.api.data; + +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RecordOffsetManagement { + + final Map> records = new HashMap<>(); + private final AtomicInteger numUnacked = new AtomicInteger(0); + + private CountDownLatch messageDrainLatch; + + public RecordOffsetManagement() { + } + + /** + * submit record + * @param position + * @return + */ + public SubmittedPosition submitRecord(RecordPosition position) { + SubmittedPosition submittedPosition = new SubmittedPosition(position); + records.computeIfAbsent(position.getPartition(), e -> new LinkedList<>()).add(submittedPosition); + // ensure thread safety in operation + synchronized (this) { + numUnacked.incrementAndGet(); + } + return submittedPosition; + } + + /** + * @param submittedPositions + * @return + */ + private RecordOffset pollOffsetWhile(Deque submittedPositions) { + RecordOffset offset = null; + // Stop pulling if there is an uncommitted breakpoint + while (canCommitHead(submittedPositions)) { + offset = submittedPositions.poll().getPosition().getOffset(); + } + return offset; + } + + private boolean canCommitHead(Deque submittedPositions) { + return submittedPositions.peek() != null && submittedPositions.peek().getAcked(); + } + + public boolean awaitAllMessages(long timeout, TimeUnit timeUnit) { + // Create a new message drain latch as a local variable to avoid SpotBugs warnings about inconsistent synchronization + // on an instance variable when invoking CountDownLatch::await outside a synchronized block + CountDownLatch messageDrainLatch; + synchronized (this) { + messageDrainLatch = new CountDownLatch(numUnacked.get()); + this.messageDrainLatch = messageDrainLatch; + } + try { + return messageDrainLatch.await(timeout, timeUnit); + } catch (InterruptedException e) { + return false; + } + } + + public CommittableOffsets committableOffsets() { + Map offsets = new HashMap<>(); + int totalCommittableMessages = 0; + int totalUncommittableMessages = 0; + int largestDequeSize = 0; + RecordPartition largestDequePartition = null; + for (Map.Entry> entry : records.entrySet()) { + RecordPartition partition = entry.getKey(); + Deque queuedRecords = entry.getValue(); + int initialDequeSize = queuedRecords.size(); + if (canCommitHead(queuedRecords)) { + RecordOffset offset = pollOffsetWhile(queuedRecords); + offsets.put(partition, offset); + } + // uncommited messages + int uncommittableMessages = queuedRecords.size(); + // committed messages + int committableMessages = initialDequeSize - uncommittableMessages; + + // calc total + totalCommittableMessages += committableMessages; + totalUncommittableMessages += uncommittableMessages; + + if (uncommittableMessages > largestDequeSize) { + largestDequeSize = uncommittableMessages; + largestDequePartition = partition; + } + } + // Clear out all empty deques from the map to keep it from growing indefinitely + records.values().removeIf(Deque::isEmpty); + return new CommittableOffsets(offsets, totalCommittableMessages, totalUncommittableMessages, + records.size(), largestDequeSize, largestDequePartition); + } + + // Synchronize in order to ensure that the number of unacknowledged messages isn't modified in the middle of a call + // to awaitAllMessages (which might cause us to decrement first, then create a new message drain latch, then count down + // that latch here, effectively double-acking the message) + private synchronized void messageAcked() { + numUnacked.decrementAndGet(); + if (messageDrainLatch != null) { + messageDrainLatch.countDown(); + } + } + + /** + * Contains a snapshot of offsets that can be committed for a source task and metadata for that offset commit + * (such as the number of messages for which offsets can and cannot be committed). + */ + public static class CommittableOffsets { + + /** + * An "empty" snapshot that contains no offsets to commit and whose metadata contains no committable or uncommitable messages. + */ + public static final CommittableOffsets EMPTY = new CommittableOffsets(Collections.emptyMap(), 0, 0, 0, 0, null); + + private final Map offsets; + private final RecordPartition largestDequePartition; + private final int numCommittableMessages; + private final int numUncommittableMessages; + private final int numDeques; + private final int largestDequeSize; + + CommittableOffsets( + Map offsets, + int numCommittableMessages, + int numUncommittableMessages, + int numDeques, + int largestDequeSize, + RecordPartition largestDequePartition) { + this.offsets = offsets != null ? new HashMap<>(offsets) : Collections.emptyMap(); + this.numCommittableMessages = numCommittableMessages; + this.numUncommittableMessages = numUncommittableMessages; + this.numDeques = numDeques; + this.largestDequeSize = largestDequeSize; + this.largestDequePartition = largestDequePartition; + } + + public Map offsets() { + return Collections.unmodifiableMap(offsets); + } + + public int numCommittableMessages() { + return numCommittableMessages; + } + + public int numUncommittableMessages() { + return numUncommittableMessages; + } + + public int numDeques() { + return numDeques; + } + + public int largestDequeSize() { + return largestDequeSize; + } + + public RecordPartition largestDequePartition() { + return largestDequePartition; + } + + public boolean hasPending() { + return numUncommittableMessages > 0; + } + + public boolean isEmpty() { + return numCommittableMessages == 0 && numUncommittableMessages == 0 && offsets.isEmpty(); + } + + public CommittableOffsets updatedWith(CommittableOffsets newerOffsets) { + Map offsets = new HashMap<>(this.offsets); + offsets.putAll(newerOffsets.offsets); + + return new CommittableOffsets( + offsets, + this.numCommittableMessages + newerOffsets.numCommittableMessages, + newerOffsets.numUncommittableMessages, + newerOffsets.numDeques, + newerOffsets.largestDequeSize, + newerOffsets.largestDequePartition); + } + } + + public class SubmittedPosition { + + private final RecordPosition position; + private final AtomicBoolean acked; + + public SubmittedPosition(RecordPosition position) { + this.position = position; + acked = new AtomicBoolean(false); + } + + /** + * Acknowledge this record; signals that its offset may be safely committed. + */ + public void ack() { + if (this.acked.compareAndSet(false, true)) { + messageAcked(); + } + } + + /** + * remove record + * + * @return + */ + public boolean remove() { + Deque deque = records.get(position.getPartition()); + if (deque == null) { + return false; + } + boolean result = deque.removeLastOccurrence(this); + if (deque.isEmpty()) { + records.remove(position.getPartition()); + } + if (result) { + messageAcked(); + } else { + log.warn("Attempted to remove record from submitted queue for partition {}, " + + "but the record has not been submitted or has already been removed", position.getPartition()); + } + return result; + } + + public RecordPosition getPosition() { + return position; + } + + public Boolean getAcked() { + return acked.get(); + } + } + +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/RecordPartition.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordPartition.java similarity index 87% rename from eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/RecordPartition.java rename to eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordPartition.java index 67734ec60a..959a6b9b3c 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/RecordPartition.java +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordPartition.java @@ -15,8 +15,9 @@ * limitations under the License. */ -package org.apache.eventmesh.openconnect.api.data; +package org.apache.eventmesh.openconnect.offsetmgmt.api.data; +import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -28,7 +29,11 @@ public class RecordPartition { * value=brokerName key=queueId, * value=queueId */ - private final Map partition; + private Map partition = new HashMap<>(); + + public RecordPartition() { + + } public RecordPartition(Map partition) { this.partition = partition; @@ -54,11 +59,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(partition); } - - @Override - public String toString() { - return "RecordPartition{" - + "partition=" + partition - + "}"; - } } diff --git a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/RecordPosition.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordPosition.java similarity index 91% rename from eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/RecordPosition.java rename to eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordPosition.java index c2e37ffbd8..0b836ab607 100644 --- a/eventmesh-openconnect/eventmesh-openconnect-java/src/main/java/org/apache/eventmesh/openconnect/api/data/RecordPosition.java +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/data/RecordPosition.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.eventmesh.openconnect.api.data; +package org.apache.eventmesh.openconnect.offsetmgmt.api.data; import java.util.Objects; @@ -25,7 +25,8 @@ public class RecordPosition { private final RecordOffset recordOffset; - public RecordPosition(RecordPartition recordPartition, RecordOffset recordOffset) { + public RecordPosition( + RecordPartition recordPartition, RecordOffset recordOffset) { this.recordPartition = recordPartition; this.recordOffset = recordOffset; } diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/ConnectorRecordPartition.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/ConnectorRecordPartition.java new file mode 100644 index 0000000000..3308654385 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/ConnectorRecordPartition.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.openconnect.offsetmgmt.api.storage; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.Map; +import java.util.Objects; + +/** + * extend record partition + */ +public class ConnectorRecordPartition extends RecordPartition { + + /** + * connect name + */ + private String connectorName; + + public ConnectorRecordPartition() { + + } + + public ConnectorRecordPartition(String connectorName, Map partition) { + super(partition); + this.connectorName = connectorName; + } + + public String getConnectorName() { + return connectorName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof ConnectorRecordPartition)) { + return false; + } + if (!super.equals(o)) { + return false; + } + ConnectorRecordPartition that = (ConnectorRecordPartition) o; + return this.connectorName.equals(that.connectorName); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), connectorName); + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/DefaultOffsetManagementServiceImpl.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/DefaultOffsetManagementServiceImpl.java new file mode 100644 index 0000000000..e31fc358f0 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/DefaultOffsetManagementServiceImpl.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.openconnect.offsetmgmt.api.storage; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.config.OffsetStorageConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; + +import java.util.List; +import java.util.Map; + +public class DefaultOffsetManagementServiceImpl implements OffsetManagementService { + + @Override + public void start() { + + } + + @Override + public void stop() { + + } + + @Override + public void persist() { + + } + + @Override + public void load() { + + } + + @Override + public void synchronize() { + + } + + @Override + public Map getPositionMap() { + return null; + } + + @Override + public RecordOffset getPosition(ConnectorRecordPartition partition) { + return null; + } + + @Override + public void putPosition(Map positions) { + + } + + @Override + public void putPosition(ConnectorRecordPartition partition, RecordOffset position) { + + } + + @Override + public void removePosition(List partitions) { + + } + + @Override + public void initialize(OffsetStorageConfig connectorConfig) { + + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/KeyValueStore.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/KeyValueStore.java new file mode 100644 index 0000000000..2d9a41290d --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/KeyValueStore.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.openconnect.offsetmgmt.api.storage; + +import java.util.Map; + +/** + * Key value based store interface. + * + * @param + * @param + */ +public interface KeyValueStore { + + /** + * Put a key/value into the store. + * + * @param key + * @param value + * @return + */ + V put(K key, V value); + + /** + * Put a set of key/value into the store. + * + * @param map + */ + void putAll(Map map); + + /** + * Remove a specified key. + * + * @param key + * @return + */ + V remove(K key); + + /** + * Get the size of current key/value store. + * + * @return + */ + int size(); + + /** + * Whether a key is contained in current store. + * + * @param key + * @return + */ + boolean containsKey(K key); + + /** + * Get the value of a key. + * + * @param key + * @return + */ + V get(K key); + + /** + * Get all data from the current store. Not recommend to use this method when the data set is large. + * + * @return + */ + Map getKVMap(); + + /** + * Load the data from back store. + * + * @return + */ + boolean load(); + + /** + * Persist all data into the store. + */ + void persist(); + + Stage getStage(); + + enum Stage { + CONNECTOR, + TASK, + POSITION, + UNIVERSAL + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/MemoryBasedKeyValueStore.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/MemoryBasedKeyValueStore.java new file mode 100644 index 0000000000..e13e1fe231 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/MemoryBasedKeyValueStore.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.openconnect.offsetmgmt.api.storage; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class MemoryBasedKeyValueStore implements KeyValueStore { + + protected Map data; + + public MemoryBasedKeyValueStore() { + this.data = new ConcurrentHashMap<>(); + } + + @Override + public V put(K key, V value) { + return this.data.put(key, value); + } + + @Override + public void putAll(Map map) { + data.putAll(map); + } + + @Override + public V remove(K key) { + return this.data.remove(key); + } + + @Override + public int size() { + return this.data.size(); + } + + @Override + public boolean containsKey(K key) { + return this.data.containsKey(key); + } + + @Override + public V get(K key) { + return this.data.get(key); + } + + @Override + public Map getKVMap() { + return this.data; + } + + @Override + public boolean load() { + return true; + } + + @Override + public void persist() { + + } + + @Override + public Stage getStage() { + return Stage.UNIVERSAL; + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetManagementService.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetManagementService.java new file mode 100644 index 0000000000..ef1dc0d30d --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetManagementService.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.openconnect.offsetmgmt.api.storage; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.config.OffsetStorageConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +import java.util.List; +import java.util.Map; + +/** + * Interface for offset manager. + */ +@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.OFFSETMGMT) +public interface OffsetManagementService { + + /** + * Start the manager. + */ + void start(); + + /** + * Stop the manager. + */ + void stop(); + + /** + * Configure class with the given key-value pairs + */ + default void configure(OffsetStorageConfig config) { + + } + + /** + * Persist position info in a persist store. + */ + void persist(); + + /** + * load position info in a persist store. + */ + void load(); + + /** + * Synchronize to other nodes. + */ + void synchronize(); + + /** + * Get the current position table. + * + * @return + */ + Map getPositionMap(); + + RecordOffset getPosition(ConnectorRecordPartition partition); + + /** + * Put a position info. + */ + void putPosition(Map positions); + + void putPosition(ConnectorRecordPartition partition, RecordOffset position); + + /** + * Remove a position info. + * + * @param partitions + */ + void removePosition(List partitions); + + void initialize(OffsetStorageConfig connectorConfig); + +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageReader.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageReader.java new file mode 100644 index 0000000000..dc17e29840 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageReader.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.openconnect.offsetmgmt.api.storage; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.Collection; +import java.util.Map; + +/** + * OffsetStorageReader + */ +public interface OffsetStorageReader { + + RecordOffset readOffset(RecordPartition recordPartition); + + Map readOffsets(Collection collection); + +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageReaderImpl.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageReaderImpl.java new file mode 100644 index 0000000000..efd087404e --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageReaderImpl.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.openconnect.offsetmgmt.api.storage; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public class OffsetStorageReaderImpl implements OffsetStorageReader { + + private final String connectorName; + + private OffsetManagementService offsetManagementService; + + public OffsetStorageReaderImpl(String connectorName, OffsetManagementService offsetManagementService) { + this.connectorName = connectorName; + this.offsetManagementService = offsetManagementService; + } + + @Override + public RecordOffset readOffset(RecordPartition partition) { + ConnectorRecordPartition connectorRecordPartition = new ConnectorRecordPartition(connectorName, partition.getPartition()); + return offsetManagementService.getPositionMap().get(connectorRecordPartition); + } + + @Override + public Map readOffsets(Collection partitions) { + Map result = new HashMap<>(); + Map allData = offsetManagementService.getPositionMap(); + for (RecordPartition key : partitions) { + ConnectorRecordPartition connectorRecordPartition = new ConnectorRecordPartition(connectorName, key.getPartition()); + if (allData.containsKey(connectorRecordPartition)) { + result.put(key, allData.get(connectorRecordPartition)); + } + } + return result; + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageWriter.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageWriter.java new file mode 100644 index 0000000000..f8b6bdc45e --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageWriter.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.openconnect.offsetmgmt.api.storage; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.util.Map; + +/** + * OffsetStorageWriter + */ +public interface OffsetStorageWriter { + + void writeOffset(RecordPartition recordPartition, RecordOffset recordOffset); + + void writeOffset(Map map); + +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageWriterImpl.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageWriterImpl.java new file mode 100644 index 0000000000..682205c4a6 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-api/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/api/storage/OffsetStorageWriterImpl.java @@ -0,0 +1,171 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.openconnect.offsetmgmt.api.storage; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordPartition; + +import java.io.Closeable; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class OffsetStorageWriterImpl implements OffsetStorageWriter, Closeable { + + private final String connectorName; + private final ExecutorService executorService = Executors.newSingleThreadExecutor(); + private OffsetManagementService offsetManagementService; + /** + * Offset data in Connect format + */ + private Map data = new HashMap<>(); + private Map toFlush = null; + + // Unique ID for each flush request to handle callbacks after timeouts + private long currentFlushId = 0; + + public OffsetStorageWriterImpl(String connectorName, OffsetManagementService offsetManagementService) { + this.connectorName = connectorName; + this.offsetManagementService = offsetManagementService; + } + + @Override + public void writeOffset(RecordPartition partition, RecordOffset position) { + ConnectorRecordPartition extendRecordPartition = new ConnectorRecordPartition(connectorName, partition.getPartition()); + data.put(extendRecordPartition, position); + } + + /** + * write offsets + * + * @param positions positions + */ + @Override + public void writeOffset(Map positions) { + for (Map.Entry offset : positions.entrySet()) { + writeOffset(offset.getKey(), offset.getValue()); + } + } + + private boolean isFlushing() { + return toFlush != null; + } + + /** + * begin flush offset + * + * @return + */ + public synchronized boolean beginFlush() { + if (isFlushing()) { + throw new RuntimeException("OffsetStorageWriter is already flushing"); + } + if (data.isEmpty()) { + return false; + } + this.toFlush = this.data; + this.data = new HashMap<>(); + return true; + } + + /** + * do flush offset + */ + public Future doFlush() { + final long flushId = currentFlushId; + return sendOffsetFuture(flushId); + } + + /** + * Cancel a flush that has been initiated by {@link #beginFlush}. + */ + public synchronized void cancelFlush() { + if (isFlushing()) { + // rollback to inited + toFlush.putAll(data); + data = toFlush; + currentFlushId++; + toFlush = null; + } + } + + private Future sendOffsetFuture(long flushId) { + FutureTask futureTask = new FutureTask<>(new SendOffsetCallback(flushId)); + executorService.submit(futureTask); + return futureTask; + } + + /** + * Closes this stream and releases any system resources associated + * with it. If the stream is already closed then invoking this + * method has no effect. + * + * @throws IOException if an I/O error occurs + */ + @Override + public void close() throws IOException { + executorService.shutdown(); + } + + /** + * send offset callback + */ + private class SendOffsetCallback implements Callable { + + long flushId; + + public SendOffsetCallback(long flushId) { + this.flushId = flushId; + } + + /** + * Computes a result, or throws an exception if unable to do so. + * + * @return computed result + * @throws Exception if unable to compute a result + */ + @Override + public Void call() { + try { + // has been canceled + if (flushId != currentFlushId) { + return null; + } + offsetManagementService.putPosition(toFlush); + log.debug("Submitting {} entries to backing store. The offsets are: {}", toFlush.size(), toFlush); + offsetManagementService.persist(); + offsetManagementService.synchronize(); + // persist finished + toFlush = null; + currentFlushId++; + } catch (Throwable throwable) { + // rollback + cancelFlush(); + } + return null; + } + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/build.gradle b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/build.gradle new file mode 100644 index 0000000000..8637d73371 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/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 "com.alibaba.nacos:nacos-client" + implementation project(":eventmesh-openconnect:eventmesh-openconnect-offsetmgmt-plugin:eventmesh-openconnect-offsetmgmt-api") + implementation project(":eventmesh-common") + testImplementation "org.mockito:mockito-core" + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/gradle.properties b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/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-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/nacos/NacosConfigService.java b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/nacos/NacosConfigService.java new file mode 100644 index 0000000000..787adbc3f7 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/src/main/java/org/apache/eventmesh/openconnect/offsetmgmt/nacos/NacosConfigService.java @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.openconnect.offsetmgmt.nacos; + +import org.apache.eventmesh.openconnect.offsetmgmt.api.config.OffsetStorageConfig; +import org.apache.eventmesh.openconnect.offsetmgmt.api.data.RecordOffset; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.ConnectorRecordPartition; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.KeyValueStore; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.MemoryBasedKeyValueStore; +import org.apache.eventmesh.openconnect.offsetmgmt.api.storage.OffsetManagementService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.Listener; +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.common.utils.JacksonUtils; +import com.fasterxml.jackson.core.type.TypeReference; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NacosConfigService implements OffsetManagementService { + + @Getter + private String serverAddr; + + @Getter + private String dataId; + + @Getter + private String group; + + private ConfigService configService; + + private Listener listener; + + public KeyValueStore positionStore; + + @Override + public void start() { + try { + configService.addListener(dataId, group, listener); + } catch (NacosException e) { + log.error("nacos start error", e); + } + } + + // merge the updated connectorRecord & recordOffset to memory store + public void mergeOffset(ConnectorRecordPartition connectorRecordPartition, RecordOffset recordOffset) { + if (null == connectorRecordPartition || connectorRecordPartition.getPartition().isEmpty()) { + return; + } + if (positionStore.getKVMap().containsKey(connectorRecordPartition)) { + RecordOffset existedOffset = positionStore.getKVMap().get(connectorRecordPartition); + // update + if (!recordOffset.equals(existedOffset)) { + positionStore.put(connectorRecordPartition, recordOffset); + } + } else { + // add new position + positionStore.put(connectorRecordPartition, recordOffset); + } + } + + @Override + public void stop() { + configService.removeListener(dataId, group, listener); + } + + @Override + public void configure(OffsetStorageConfig config) { + + } + + // only file based storage need to imply + @Override + public void persist() { + + } + + @Override + public void load() { + + } + + @Override + public void synchronize() { + try { + Map recordMap = positionStore.getKVMap(); + + List> recordToSyncList = new ArrayList<>(); + for (Map.Entry entry : recordMap.entrySet()) { + Map synchronizeMap = new HashMap<>(); + synchronizeMap.put("connectorRecordPartition", entry.getKey()); + synchronizeMap.put("recordOffset", entry.getValue()); + recordToSyncList.add(synchronizeMap); + } + log.info("start publish config: dataId={}|group={}|value={}", dataId, group, recordToSyncList); + configService.publishConfig(dataId, group, JacksonUtils.toJson(recordToSyncList)); + } catch (NacosException e) { + throw new RuntimeException("Nacos Service publish config error", e); + } + } + + @Override + public Map getPositionMap() { + // get from memory storage first + if (positionStore.getKVMap() == null || positionStore.getKVMap().isEmpty()) { + try { + Map configMap = JacksonUtils.toObj(configService.getConfig(dataId, group, 5000L), + new TypeReference>() { + }); + log.info("nacos position map {}", configMap); + return configMap; + } catch (NacosException e) { + throw new RuntimeException(e); + } + } + log.info("memory position map {}", positionStore.getKVMap()); + return positionStore.getKVMap(); + } + + @Override + public RecordOffset getPosition(ConnectorRecordPartition partition) { + // get from memory storage first + if (positionStore.get(partition) == null) { + try { + Map recordMap = JacksonUtils.toObj(configService.getConfig(dataId, group, 5000L), + new TypeReference>() { + }); + log.info("nacos record position {}", recordMap.get(partition)); + return recordMap.get(partition); + } catch (NacosException e) { + throw new RuntimeException(e); + } + } + log.info("memory record position {}", positionStore.get(partition)); + return positionStore.get(partition); + } + + @Override + public void putPosition(Map positions) { + positionStore.putAll(positions); + } + + @Override + public void putPosition(ConnectorRecordPartition partition, RecordOffset position) { + positionStore.put(partition, position); + } + + @Override + public void removePosition(List partitions) { + if (null == partitions) { + return; + } + for (ConnectorRecordPartition partition : partitions) { + positionStore.remove(partition); + } + } + + @Override + public void initialize(OffsetStorageConfig config) { + this.serverAddr = config.getOffsetStorageAddr(); + this.dataId = config.getExtensions().get("dataId"); + this.group = config.getExtensions().get("group"); + this.positionStore = new MemoryBasedKeyValueStore<>(); + try { + configService = NacosFactory.createConfigService(serverAddr); + } catch (NacosException e) { + log.error("nacos init error", e); + } + this.listener = new Listener() { + + @Override + public Executor getExecutor() { + return null; + } + + @Override + public void receiveConfigInfo(String configInfo) { + log.info("nacos config service receive configInfo: {}", configInfo); + List> recordOffsetList = JacksonUtils.toObj(configInfo, + new TypeReference>>() { + }); + + for (Map recordPartitionOffsetMap : recordOffsetList) { + ConnectorRecordPartition connectorRecordPartition = JacksonUtils.toObj( + JacksonUtils.toJson(recordPartitionOffsetMap.get("connectorRecordPartition")), + ConnectorRecordPartition.class); + RecordOffset recordOffset = JacksonUtils.toObj(JacksonUtils.toJson(recordPartitionOffsetMap.get("recordOffset")), + RecordOffset.class); + // update the offset in memory store + mergeOffset(connectorRecordPartition, recordOffset); + } + } + }; + + } +} diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.offsetmgmt.api.storage.OffsetManagementService b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.offsetmgmt.api.storage.OffsetManagementService new file mode 100644 index 0000000000..a7e24c70a2 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/eventmesh-openconnect-offsetmgmt-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.openconnect.offsetmgmt.api.storage.OffsetManagementService @@ -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.openconnect.offsetmgmt.nacos.NacosConfigService \ No newline at end of file diff --git a/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/gradle.properties b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-plugin/gradle.properties new file mode 100644 index 0000000000..a9fd83fea0 --- /dev/null +++ b/eventmesh-openconnect/eventmesh-openconnect-offsetmgmt-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-operator/.dockerignore b/eventmesh-operator/.dockerignore new file mode 100644 index 0000000000..0f046820f1 --- /dev/null +++ b/eventmesh-operator/.dockerignore @@ -0,0 +1,4 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore build and test binaries. +bin/ +testbin/ diff --git a/eventmesh-operator/.gitignore b/eventmesh-operator/.gitignore new file mode 100644 index 0000000000..e917e5cefe --- /dev/null +++ b/eventmesh-operator/.gitignore @@ -0,0 +1,26 @@ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin +testbin/* +Dockerfile.cross + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Kubernetes Generated files - skip generated files, except for vendored files + +!vendor/**/zz_generated.* + +# editor and IDE paraphernalia +.idea +*.swp +*.swo +*~ diff --git a/eventmesh-operator/Dockerfile b/eventmesh-operator/Dockerfile new file mode 100644 index 0000000000..14a2e63f0d --- /dev/null +++ b/eventmesh-operator/Dockerfile @@ -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. +# + +# Build the manager binary +FROM golang:1.19 as builder +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +COPY main.go main.go +COPY api/ api/ +COPY controllers/ controllers/ +COPY share/ share/ + +# Build +# the GOARCH has not a default value to allow the binary be built according to the host where the command +# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO +# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, +# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager main.go + +# Use distroless as minimal base image to package the manager binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM gcr.io/distroless/static:nonroot +WORKDIR / +COPY --from=builder /workspace/manager . +USER 65532:65532 + +ENTRYPOINT ["/manager"] diff --git a/eventmesh-operator/Makefile b/eventmesh-operator/Makefile new file mode 100644 index 0000000000..285b47a8c7 --- /dev/null +++ b/eventmesh-operator/Makefile @@ -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. +# + +# VERSION defines the project version for the bundle. +# Update this value when you upgrade the version of your project. +# To re-generate a bundle for another specific version without changing the standard setup, you can: +# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) +# - use environment variables to overwrite this value (e.g export VERSION=0.0.2) +VERSION ?= 0.0.1 + +# CHANNELS define the bundle channels used in the bundle. +# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") +# To re-generate a bundle for other specific channels without changing the standard setup, you can: +# - use the CHANNELS as arg of the bundle target (e.g make bundle CHANNELS=candidate,fast,stable) +# - use environment variables to overwrite this value (e.g export CHANNELS="candidate,fast,stable") +ifneq ($(origin CHANNELS), undefined) +BUNDLE_CHANNELS := --channels=$(CHANNELS) +endif + +# DEFAULT_CHANNEL defines the default channel used in the bundle. +# Add a new line here if you would like to change its default config. (E.g DEFAULT_CHANNEL = "stable") +# To re-generate a bundle for any other default channel without changing the default setup, you can: +# - use the DEFAULT_CHANNEL as arg of the bundle target (e.g make bundle DEFAULT_CHANNEL=stable) +# - use environment variables to overwrite this value (e.g export DEFAULT_CHANNEL="stable") +ifneq ($(origin DEFAULT_CHANNEL), undefined) +BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) +endif +BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) + +# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images. +# This variable is used to construct full image tags for bundle and catalog images. +# +# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both +# eventmesh/eventmesh-operator-bundle:$VERSION and eventmesh/eventmesh-operator-catalog:$VERSION. +IMAGE_TAG_BASE ?= eventmesh/eventmesh-operator + +# BUNDLE_IMG defines the image:tag used for the bundle. +# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:) +BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:v$(VERSION) + +# BUNDLE_GEN_FLAGS are the flags passed to the operator-sdk generate bundle command +BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) + +# USE_IMAGE_DIGESTS defines if images are resolved via tags or digests +# You can enable this value if you would like to use SHA Based Digests +# To enable set flag to true +USE_IMAGE_DIGESTS ?= false +ifeq ($(USE_IMAGE_DIGESTS), true) + BUNDLE_GEN_FLAGS += --use-image-digests +endif + +# Set the Operator SDK version to use. By default, what is installed on the system is used. +# This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit. +OPERATOR_SDK_VERSION ?= v1.31.0 + +# Image URL to use all building/pushing image targets +IMG ?= controller:latest +# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. +ENVTEST_K8S_VERSION = 1.26.0 + +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + +# Setting SHELL to bash allows bash commands to be executed by recipes. +# Options are set to exit when a recipe line exits non-zero or a piped command fails. +SHELL = /usr/bin/env bash -o pipefail +.SHELLFLAGS = -ec + +.PHONY: all +all: build + +##@ General + +# The help target prints out all targets with their descriptions organized +# beneath their categories. The categories are represented by '##@' and the +# target descriptions by '##'. The awk commands is responsible for reading the +# entire set of makefiles included in this invocation, looking for lines of the +# file as xyz: ## something, and then pretty-format the target and help. Then, +# if there's a line with ##@ something, that gets pretty-printed as a category. +# More info on the usage of ANSI control characters for terminal formatting: +# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters +# More info on the awk command: +# http://linuxcommand.org/lc3_adv_awk.php + +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +##@ Development + +.PHONY: manifests +manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. + $(CONTROLLER_GEN) rbac:roleName=eventmesh-operator crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases + +.PHONY: generate +generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." + +.PHONY: fmt +fmt: ## Run go fmt against code. + go fmt ./... + +.PHONY: vet +vet: ## Run go vet against code. + go vet ./... + +.PHONY: test +test: manifests generate fmt vet envtest ## Run tests. + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out + +##@ Build + +.PHONY: build +build: manifests generate fmt vet ## Build manager binary. + go build -o bin/manager main.go + +.PHONY: run +run: manifests generate fmt vet ## Run a controller from your host. + go run ./main.go + +# If you wish built the manager image targeting other platforms you can use the --platform flag. +# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it. +# More info: https://docs.docker.com/develop/develop-images/build_enhancements/ +.PHONY: docker-build +docker-build: test ## Build docker image with the manager. + docker build -t ${IMG} . + +.PHONY: docker-push +docker-push: ## Push docker image with the manager. + docker push ${IMG} + +# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple +# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: +# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/ +# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/ +# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=> then the export will fail) +# To properly provided solutions that supports more than one platform you should use this option. +PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le +.PHONY: docker-buildx +docker-buildx: test ## Build and push docker image for the manager for cross-platform support + # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile + sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross + - docker buildx create --name project-v3-builder + docker buildx use project-v3-builder + - docker buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross . + - docker buildx rm project-v3-builder + rm Dockerfile.cross + +##@ Deployment + +ifndef ignore-not-found + ignore-not-found = false +endif + +.PHONY: install +install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. + kubectl create -f config/crd/bases/eventmesh-operator.eventmesh_runtimes.yaml + kubectl create -f config/crd/bases/eventmesh-operator.eventmesh_connectors.yaml + +.PHONY: uninstall +uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. + kubectl delete --ignore-not-found=$(ignore-not-found) -f config/crd/bases/eventmesh-operator.eventmesh_runtimes.yaml + kubectl delete --ignore-not-found=$(ignore-not-found) -f config/crd/bases/eventmesh-operator.eventmesh_connectors.yaml + +.PHONY: create +create: + kubectl create -f config/samples/eventmesh_v1_runtime.yaml + kubectl create -f config/samples/eventmesh_v1_runtime_cluster.yaml + kubectl create -f config/samples/eventmesh_v1_connectors_rocketmq.yaml + +.PHONY: delete +delete: + kubectl delete --ignore-not-found=$(ignore-not-found) -f config/samples/eventmesh_v1_runtime.yaml + kubectl delete --ignore-not-found=$(ignore-not-found) -f config/samples/eventmesh_v1_runtime_cluster.yaml + kubectl delete --ignore-not-found=$(ignore-not-found) -f config/samples/eventmesh_v1_connectors_rocketmq.yaml + +.PHONY: deploy +deploy: manifests install ## Deploy controller to the K8s cluster specified in ~/.kube/config. + kubectl create -f config/rbac/service_account.yaml + kubectl create -f config/rbac/role.yaml + kubectl create -f config/rbac/role_binding.yaml + kubectl create -f config/samples/eventmesh_operator.yaml + +.PHONY: undeploy +undeploy: uninstall ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. + kubectl delete --ignore-not-found=$(ignore-not-found) -f config/rbac/service_account.yaml + kubectl delete --ignore-not-found=$(ignore-not-found) -f config/rbac/role.yaml + kubectl delete --ignore-not-found=$(ignore-not-found) -f config/rbac/role_binding.yaml + kubectl delete --ignore-not-found=$(ignore-not-found) -f config/samples/eventmesh_operator.yaml + +##@ Build Dependencies + +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +## Tool Binaries +KUSTOMIZE ?= $(LOCALBIN)/kustomize +CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen +ENVTEST ?= $(LOCALBIN)/setup-envtest + +## Tool Versions +KUSTOMIZE_VERSION ?= v3.8.7 +CONTROLLER_TOOLS_VERSION ?= v0.11.1 + +KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" +.PHONY: kustomize +kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading. +$(KUSTOMIZE): $(LOCALBIN) + @if test -x $(LOCALBIN)/kustomize && ! $(LOCALBIN)/kustomize version | grep -q $(KUSTOMIZE_VERSION); then \ + echo "$(LOCALBIN)/kustomize version is not expected $(KUSTOMIZE_VERSION). Removing it before installing."; \ + rm -rf $(LOCALBIN)/kustomize; \ + fi + test -s $(LOCALBIN)/kustomize || { curl -Ss $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); } + +.PHONY: controller-gen +controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. If wrong version is installed, it will be overwritten. +$(CONTROLLER_GEN): $(LOCALBIN) + test -s $(LOCALBIN)/controller-gen && $(LOCALBIN)/controller-gen --version | grep -q $(CONTROLLER_TOOLS_VERSION) || \ + GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION) + +.PHONY: envtest +envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. +$(ENVTEST): $(LOCALBIN) + test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + +.PHONY: operator-sdk +OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk +operator-sdk: ## Download operator-sdk locally if necessary. +ifeq (,$(wildcard $(OPERATOR_SDK))) +ifeq (, $(shell which operator-sdk 2>/dev/null)) + @{ \ + set -e ;\ + mkdir -p $(dir $(OPERATOR_SDK)) ;\ + OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ + curl -sSLo $(OPERATOR_SDK) https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk_$${OS}_$${ARCH} ;\ + chmod +x $(OPERATOR_SDK) ;\ + } +else +OPERATOR_SDK = $(shell which operator-sdk) +endif +endif + +.PHONY: bundle +bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files. + $(OPERATOR_SDK) generate kustomize manifests -q + cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) + $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS) + $(OPERATOR_SDK) bundle validate ./bundle + +.PHONY: bundle-build +bundle-build: ## Build the bundle image. + docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) . + +.PHONY: bundle-push +bundle-push: ## Push the bundle image. + $(MAKE) docker-push IMG=$(BUNDLE_IMG) + +.PHONY: opm +OPM = ./bin/opm +opm: ## Download opm locally if necessary. +ifeq (,$(wildcard $(OPM))) +ifeq (,$(shell which opm 2>/dev/null)) + @{ \ + set -e ;\ + mkdir -p $(dir $(OPM)) ;\ + OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ + curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.23.0/$${OS}-$${ARCH}-opm ;\ + chmod +x $(OPM) ;\ + } +else +OPM = $(shell which opm) +endif +endif + +# A comma-separated list of bundle images (e.g. make catalog-build BUNDLE_IMGS=example.com/operator-bundle:v0.1.0,example.com/operator-bundle:v0.2.0). +# These images MUST exist in a registry and be pull-able. +BUNDLE_IMGS ?= $(BUNDLE_IMG) + +# The image tag given to the resulting catalog image (e.g. make catalog-build CATALOG_IMG=example.com/operator-catalog:v0.2.0). +CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:v$(VERSION) + +# Set CATALOG_BASE_IMG to an existing catalog image tag to add $BUNDLE_IMGS to that image. +ifneq ($(origin CATALOG_BASE_IMG), undefined) +FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) +endif + +# Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'. +# This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see: +# https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator +.PHONY: catalog-build +catalog-build: opm ## Build a catalog image. + $(OPM) index add --container-tool docker --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT) + +# Push the catalog image. +.PHONY: catalog-push +catalog-push: ## Push a catalog image. + $(MAKE) docker-push IMG=$(CATALOG_IMG) diff --git a/eventmesh-operator/PROJECT b/eventmesh-operator/PROJECT new file mode 100644 index 0000000000..9b15faf803 --- /dev/null +++ b/eventmesh-operator/PROJECT @@ -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. +# + +# Code generated by tool. DO NOT EDIT. +# This file is used to track the info used to scaffold your project +# and allow the plugins properly work. +# More info: https://book.kubebuilder.io/reference/project-config.html +domain: eventmesh +layout: +- go.kubebuilder.io/v3 +plugins: + manifests.sdk.operatorframework.io/v2: {} + scorecard.sdk.operatorframework.io/v2: {} +projectName: eventmesh-operator +repo: github.com/apache/eventmesh/eventmesh-operator +resources: +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: eventmesh + group: eventmesh-operator + kind: EventMeshOperator + path: github.com/apache/eventmesh/eventmesh-operator/api/v1 + version: v1 +version: "3" diff --git a/eventmesh-operator/README.md b/eventmesh-operator/README.md new file mode 100644 index 0000000000..22e4604d61 --- /dev/null +++ b/eventmesh-operator/README.md @@ -0,0 +1,96 @@ +## **EventMesh Operator Quick Start** + +### Preparing: +- docker +- golang (version 1.19) +- kubernetes(kubectl) + **Note:** There is some compatibility between kubernetes an docker, please check the version compatibility between them and download the corresponding version to ensure that they work properly together. + +### Quick Start + +#### Deployment + +1. Go to the eventmesh-operator directory. +```shell +cd eventmesh-operator +``` + +2. Install CRD into the specified k8s cluster. +```shell +make install + +# Uninstall CRDs from the K8s cluster +make uninstall +``` + +If you get error eventmesh-operator/bin/controller-gen: No such file or directory +Run the following command: +```shell +# download controller-gen locally if necessary. +make controller-gen +# download kustomize locally if necessary. +make kustomize +``` + +Success +```shell +# run the following command to view crds information: +kubectl get crds + +NAME CREATED AT +connectors.eventmesh-operator.eventmesh 2023-11-28T01:35:21Z +runtimes.eventmesh-operator.eventmesh 2023-11-28T01:35:21Z +``` + +3. Create and delete CRs: + Custom resource objects are located at: /config/samples + When deleting CR, simply replace create with delete. +```shell +# Create CR for eventmesh-runtime、eventmesh-connector-rocketmq,Creating a clusterIP lets eventmesh-runtime communicate with other components. +make create + +#success: +configmap/runtime-config created +runtime.eventmesh-operator.eventmesh/eventmesh-runtime created +service/runtime-cluster-service created +configmap/connector-rocketmq-config created +connectors.eventmesh-operator.eventmesh/connector-rocketmq created + +# View the created Service. +kubectl get service +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +runtime-cluster-service ClusterIP 10.109.209.72 10000/TCP 17s + +# Delete CR +make delete +``` + +4. Run eventmesh-operator create pods +```shell +make run +# success run log +go fmt ./... +go vet ./... +go run ./main.go +INFO controller-runtime.metrics Metrics server is starting to listen {"addr": ":9020"} +INFO setup starting manager +INFO Starting server {"kind": "health probe", "addr": "[::]:8081"} +INFO Starting server {"path": "/metrics", "kind": "metrics", "addr": "[::]:9020"} +INFO runtime Creating a new eventMeshRuntime StatefulSet. {"StatefulSet.Namespace": "default", "StatefulSet.Name": "eventmesh-runtime-0-a"} +INFO connector Creating a new Connector StatefulSet. {"StatefulSet.Namespace": "default", "StatefulSet.Name": "connector-rocketmq"} +INFO runtime Successful reconciliation! +INFO connector Successful reconciliation! + + + +# After the pods are successfully started, run the following command to view pods. +kubectl get pods +NAME READY STATUS RESTARTS AGE +connector-rocketmq-0 1/1 Running 0 12m +eventmesh-runtime-0-a-0 1/1 Running 0 12m + +kubectl get pods -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +connector-rocketmq-0 1/1 Running 0 13m 10.244.0.21 minikube +eventmesh-runtime-0-a-0 1/1 Running 0 13m 10.244.0.20 minikube +``` diff --git a/eventmesh-operator/api/v1/connectors_types.go b/eventmesh-operator/api/v1/connectors_types.go new file mode 100644 index 0000000000..0e6f9026fa --- /dev/null +++ b/eventmesh-operator/api/v1/connectors_types.go @@ -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 v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// ConnectorsSpec defines the desired state of ConnectorsSpec +type ConnectorsSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + // Foo is an example field of Connectors. Edit connectors_types.go to remove/update + + // Size of connector + Size int `json:"size"` + // ConnectorContainers define some configuration + ConnectorContainers []corev1.Container `json:"connectorContainers"` + // HostNetwork can be true or false + HostNetwork bool `json:"hostNetwork,omitempty"` + // DNSPolicy Set DNS policy for the pod. + DNSPolicy corev1.DNSPolicy `json:"dnsPolicy,omitempty"` + // Volumes define the connector config + Volumes []corev1.Volume `json:"volumes"` + // ImagePullPolicy defines how the image is pulled + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + // PodSecurityContext Pod Security Context + PodSecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"` + // ContainerSecurityContext Container Security Context + ContainerSecurityContext *corev1.SecurityContext `json:"containerSecurityContext,omitempty"` + // ImagePullSecrets The secrets used to pull image from private registry + ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"` + // Affinity the pod's scheduling constraints + Affinity *corev1.Affinity `json:"affinity,omitempty"` + // Tolerations the pod's tolerations. + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + // NodeSelector is a selector which must be true for the pod to fit on a node + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // PriorityClassName indicates the pod's priority + PriorityClassName string `json:"priorityClassName,omitempty"` + // ServiceAccountName + ServiceAccountName string `json:"serviceAccountName,omitempty"` +} + +// ConnectorsStatus defines the observed state of ConnectorsStatus +type ConnectorsStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file + + Size int `json:"size"` + + Nodes []string `json:"nodes"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// Connectors is the Schema for the Connectors API +type Connectors struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ConnectorsSpec `json:"spec,omitempty"` + Status ConnectorsStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// ConnectorsList contains a list of Connectors +type ConnectorsList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Connectors `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Connectors{}, &ConnectorsList{}) +} diff --git a/eventmesh-operator/api/v1/groupversion_info.go b/eventmesh-operator/api/v1/groupversion_info.go new file mode 100644 index 0000000000..6e5593efcc --- /dev/null +++ b/eventmesh-operator/api/v1/groupversion_info.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 v1 contains API Schema definitions for the eventmesh-operator v1 API group +// +kubebuilder:object:generate=true +// +groupName=eventmesh-operator.eventmesh +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "eventmesh-operator.eventmesh", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/eventmesh-operator/api/v1/runtime_types.go b/eventmesh-operator/api/v1/runtime_types.go new file mode 100644 index 0000000000..46e7a2f80a --- /dev/null +++ b/eventmesh-operator/api/v1/runtime_types.go @@ -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 v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// RuntimeSpec defines the desired state of Runtime +type RuntimeSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + // Foo is an example field of Runtime. Edit runtime_types.go to remove/update + + // Size of runtime + Size int `json:"size"` + // AllowRestart defines whether allow pod restart + AllowRestart bool `json:"allowRestart"` + // ReplicaPerGroup each runtime's replica number + ReplicaPerGroup int `json:"replicaPerGroup"` + // RuntimePodTemplate define some configuration + RuntimePodTemplate corev1.PodTemplate `json:"runtimePodTemplate"` + // PodSecurityContext Pod Security Context + PodSecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"` + // ContainerSecurityContext Container Security Context + ContainerSecurityContext *corev1.SecurityContext `json:"containerSecurityContext,omitempty"` +} + +// RuntimeStatus defines the observed state of Runtime +type RuntimeStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file + + Size int `json:"size"` + + Nodes []string `json:"nodes"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// Runtime is the Schema for the Runtime API +type Runtime struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec RuntimeSpec `json:"spec,omitempty"` + Status RuntimeStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// RuntimeList contains a list of Runtime +type RuntimeList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Runtime `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Runtime{}, &RuntimeList{}) +} diff --git a/eventmesh-operator/api/v1/zz_generated.deepcopy.go b/eventmesh-operator/api/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..765f5d68db --- /dev/null +++ b/eventmesh-operator/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,275 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 controller-gen. DO NOT EDIT. + +package v1 + +import ( + corev1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Connectors) DeepCopyInto(out *Connectors) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Connectors. +func (in *Connectors) DeepCopy() *Connectors { + if in == nil { + return nil + } + out := new(Connectors) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Connectors) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectorsList) DeepCopyInto(out *ConnectorsList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Connectors, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectorsList. +func (in *ConnectorsList) DeepCopy() *ConnectorsList { + if in == nil { + return nil + } + out := new(ConnectorsList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ConnectorsList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectorsSpec) DeepCopyInto(out *ConnectorsSpec) { + *out = *in + if in.ConnectorContainers != nil { + in, out := &in.ConnectorContainers, &out.ConnectorContainers + *out = make([]corev1.Container, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]corev1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.PodSecurityContext != nil { + in, out := &in.PodSecurityContext, &out.PodSecurityContext + *out = new(corev1.PodSecurityContext) + (*in).DeepCopyInto(*out) + } + if in.ContainerSecurityContext != nil { + in, out := &in.ContainerSecurityContext, &out.ContainerSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make([]corev1.LocalObjectReference, len(*in)) + copy(*out, *in) + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(corev1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectorsSpec. +func (in *ConnectorsSpec) DeepCopy() *ConnectorsSpec { + if in == nil { + return nil + } + out := new(ConnectorsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectorsStatus) DeepCopyInto(out *ConnectorsStatus) { + *out = *in + if in.Nodes != nil { + in, out := &in.Nodes, &out.Nodes + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectorsStatus. +func (in *ConnectorsStatus) DeepCopy() *ConnectorsStatus { + if in == nil { + return nil + } + out := new(ConnectorsStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Runtime) DeepCopyInto(out *Runtime) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Runtime. +func (in *Runtime) DeepCopy() *Runtime { + if in == nil { + return nil + } + out := new(Runtime) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Runtime) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RuntimeList) DeepCopyInto(out *RuntimeList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Runtime, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuntimeList. +func (in *RuntimeList) DeepCopy() *RuntimeList { + if in == nil { + return nil + } + out := new(RuntimeList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RuntimeList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RuntimeSpec) DeepCopyInto(out *RuntimeSpec) { + *out = *in + in.RuntimePodTemplate.DeepCopyInto(&out.RuntimePodTemplate) + if in.PodSecurityContext != nil { + in, out := &in.PodSecurityContext, &out.PodSecurityContext + *out = new(corev1.PodSecurityContext) + (*in).DeepCopyInto(*out) + } + if in.ContainerSecurityContext != nil { + in, out := &in.ContainerSecurityContext, &out.ContainerSecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuntimeSpec. +func (in *RuntimeSpec) DeepCopy() *RuntimeSpec { + if in == nil { + return nil + } + out := new(RuntimeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RuntimeStatus) DeepCopyInto(out *RuntimeStatus) { + *out = *in + if in.Nodes != nil { + in, out := &in.Nodes, &out.Nodes + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuntimeStatus. +func (in *RuntimeStatus) DeepCopy() *RuntimeStatus { + if in == nil { + return nil + } + out := new(RuntimeStatus) + in.DeepCopyInto(out) + return out +} diff --git a/eventmesh-operator/config/crd/bases/eventmesh-operator.eventmesh_connectors.yaml b/eventmesh-operator/config/crd/bases/eventmesh-operator.eventmesh_connectors.yaml new file mode 100644 index 0000000000..c62dbd8c56 --- /dev/null +++ b/eventmesh-operator/config/crd/bases/eventmesh-operator.eventmesh_connectors.yaml @@ -0,0 +1,4095 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: connectors.eventmesh-operator.eventmesh +spec: + group: eventmesh-operator.eventmesh + names: + kind: Connectors + listKind: ConnectorsList + plural: connectors + singular: connectors + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Connectors is the Schema for the Connectors API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ConnectorsSpec defines the desired state of ConnectorsSpec + properties: + affinity: + description: Affinity the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + connectorContainers: + description: ConnectorContainers define some configuration + items: + description: A single application container that you want to run + within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s + CMD is used if this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. If a variable + cannot be resolved, the reference in the input string will + be unchanged. Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the variable + exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The container image''s ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: + i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must be + a C_IDENTIFIER. All invalid keys will be reported as an event + when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take + precedence. Values defined by an Env with a duplicate key + will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set + of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each + key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container + is created. If the handler fails, the container is terminated + and restarted according to its restart policy. Other management + of the container blocks until the hook completes. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward compatibility. + There are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container + is terminated due to an API request or management event + such as liveness/startup probe failure, preemption, resource + contention, etc. The handler is not called if the container + crashes or exits. The Pod''s termination grace period + countdown begins before the PreStop hook is executed. + Regardless of the outcome of the handler, the container + will eventually terminate within the Pod''s termination + grace period (unless delayed by finalizers). Other management + of the container blocks until the hook completes or until + the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward compatibility. + There are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. More + info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + This is a beta field and requires enabling GRPCContainerProbe + feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not + specifying a port here DOES NOT prevent that port from being + exposed. Any port which is listening on the default "0.0.0.0" + address inside a container will be accessible from the network. + Modifying this array with strategic merge patch may corrupt + the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a + single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP + address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If + specified, this must be a valid port number, 0 < x < + 65536. If HostNetwork is specified, this must match + ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a pod + must have a unique name. Name for the port that can + be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe + fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + This is a beta field and requires enabling GRPCContainerProbe + feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the + container should be run with. If set, the fields of SecurityContext + override the equivalent fields of PodSecurityContext. More + info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by + the container runtime. Note that this field cannot be + set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent to + root on the host. Defaults to false. Note that this field + cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to + use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a + non-root user. If true, the Kubelet will validate the + image at runtime to ensure that it does not run as UID + 0 (root) and fail to start the container if it does. If + unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a + random SELinux context for each container. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile + must be preconfigured on the node to work. Must be + a descending path, relative to the kubelet's configured + seccomp profile location. Must only be set if type + is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - + a profile defined in a file on the node should be + used. RuntimeDefault - the container runtime default + profile should be used. Unconfined - no profile should + be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is + alpha-level and will only be honored by components + that enable the WindowsHostProcessContainers feature + flag. Setting this field without the feature flag + will result in errors when validating the Pod. All + of a Pod's containers must have the same effective + HostProcess value (it is not allowed to have a mix + of HostProcess containers and non-HostProcess containers). In + addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed until + this completes successfully. If this probe fails, the Pod + will be restarted, just as if the livenessProbe failed. This + can be used to provide different probe parameters at the beginning + of a Pod''s lifecycle, when it might take a long time to load + data or warm a cache, than during steady-state operation. + This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + This is a beta field and requires enabling GRPCContainerProbe + feature gate. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, reads + from stdin in the container will always result in EOF. Default + is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the + stdin channel after it has been opened by a single attach. + When stdin is true the stdin stream will remain open across + multiple attach sessions. If stdinOnce is set to true, stdin + is opened on container start, is empty until the first client + attaches to stdin, and then remains open and accepts data + until the client disconnects, at which time stdin is closed + and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin + will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the + container''s termination message will be written is mounted + into the container''s filesystem. Message written is intended + to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. + The total message length across all containers will be limited + to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be + populated. File will use the contents of terminationMessagePath + to populate the container status message on both success and + failure. FallbackToLogsOnError will use the last chunk of + container log output if the termination message file is empty + and the container exited with an error. The log output is + limited to 2048 bytes or 80 lines, whichever is smaller. Defaults + to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for + itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be + used by the container. + items: + description: volumeDevice describes a mapping of a raw block + device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container + that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other + way around. When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + containerSecurityContext: + description: ContainerSecurityContext Container Security Context + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process + can gain more privileges than its parent process. This bool + directly controls if the no_new_privs flag will be set on the + container process. AllowPrivilegeEscalation is true always when + the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container + runtime. Note that this field cannot be set when spec.os.name + is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged + containers are essentially equivalent to root on the host. Defaults + to false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for + the containers. The default is DefaultProcMount which uses the + container runtime defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If + seccomp options are provided at both the pod & container level, + the container options override the pod options. Note that this + field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will + be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is alpha-level + and will only be honored by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature flag + will result in errors when validating the Pod. All of a + Pod's containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + dnsPolicy: + description: DNSPolicy Set DNS policy for the pod. + type: string + hostNetwork: + description: HostNetwork can be true or false + type: boolean + imagePullPolicy: + description: ImagePullPolicy defines how the image is pulled + type: string + imagePullSecrets: + description: ImagePullSecrets The secrets used to pull image from + private registry + items: + description: LocalObjectReference contains enough information to + let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a selector which must be true for the + pod to fit on a node + type: object + priorityClassName: + description: PriorityClassName indicates the pod's priority + type: string + securityContext: + description: PodSecurityContext Pod Security Context + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is alpha-level + and will only be honored by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature flag + will result in errors when validating the Pod. All of a + Pod's containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + description: ServiceAccountName + type: string + size: + description: Size of connector + type: integer + tolerations: + description: Tolerations the pod's tolerations. + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + volumes: + description: Volumes define the connector config + items: + description: Volume represents a named volume in a pod that may + be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent disk + resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on + the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the + blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob + storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount + on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains + Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that + shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, + rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is the + path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached and + mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to + be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: 'volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate + this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair in + the Data field of the referenced ConfigMap will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the ConfigMap, the volume setup will error unless it is + marked optional. Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral + storage that is handled by certain external CSI drivers (Beta + feature). + properties: + driver: + description: driver is the name of the CSI driver that handles + this volume. Consult with your admin for the correct name + as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated + CSI driver which will determine the default filesystem + to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to the + secret object containing sensitive information to pass + to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the secret + object contains more than one secret, all secret references + are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific properties + that are passed to the CSI driver. Consult your driver's + documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod + that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created files + by default. Must be a Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: + only annotations, labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to set permissions + on this file, must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This might + be in conflict with other options that affect the + file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path + name of the file to be created. Must not be absolute + or contain the ''..'' path. Must be utf-8 encoded. + The first item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory that + shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium + should back this directory. The default is "" which means + to use the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage + required for this EmptyDir volume. The size limit is also + applicable for memory medium. The maximum usage on memory + medium EmptyDir would be the minimum value between the + SizeLimit specified here and the sum of memory limits + of all containers in a pod. The default is nil which means + that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is tied + to the pod that defines it - it will be created before the + pod starts, and deleted when the pod is removed. \n Use this + if: a) the volume is only needed while the pod runs, b) features + of normal volumes like restoring from snapshot or capacity + tracking are needed, c) the storage driver is specified through + a storage class, and d) the storage driver supports dynamic + volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this volume + type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n Use + CSI for light-weight local ephemeral volumes if the CSI driver + is meant to be used that way - see the documentation of the + driver for more information. \n A pod can use both types of + ephemeral volumes and persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to + provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the PVC + will be deleted together with the pod. The name of the + PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too long). \n + An existing PVC with that name that is not owned by the + pod will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC + is meant to be used by the pod, the PVC has to updated + with an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may be useful + when manually reconstructing a broken cluster. \n This + field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, must + not be nil." + properties: + metadata: + description: May contain labels and annotations that + will be copied into the PVC when creating it. No other + fields are allowed and will be rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the PVC + that gets created from this template. The same fields + as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the + provisioner or an external controller can support + the specified data source, it will create a new + volume based on the contents of the specified + data source. When the AnyVolumeDataSource feature + gate is enabled, dataSource contents will be copied + to dataSourceRef, and dataSourceRef contents will + be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, + then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object + from which to populate the volume with data, if + a non-empty volume is desired. This may be any + object from a non-empty API group (non core object) + or a PersistentVolumeClaim object. When this field + is specified, volume binding will only succeed + if the type of the specified object matches some + installed volume populator or dynamic provisioner. + This field will replace the functionality of the + dataSource field and as such if both fields are + non-empty, they must have the same value. For + backwards compatibility, when namespace isn''t + specified in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same value + automatically if one of them is empty and the + other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the + same value and must be empty. There are three + important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types + of objects, dataSourceRef allows any non-core + object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping + them), dataSourceRef preserves all values, and + generates an error if a disallowed value is specified. + * While dataSource only allows local objects, + dataSourceRef allows objects in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the + namespace field of dataSourceRef requires the + CrossNamespaceVolumeDataSource feature gate to + be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace + is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant documentation + for details. (Alpha) This field requires the + CrossNamespaceVolumeDataSource feature gate + to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than previous + value but must still be higher than capacity recorded + in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, + defined in spec.resourceClaims, that are used + by this container. \n This is an alpha field + and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable." + items: + description: ResourceClaim references one + entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available inside + a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. If Requests + is omitted for a container, it defaults to + Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: 'storageClassName is the name of the + StorageClass required by the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume + is required by the claim. Value of Filesystem + is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is + attached to a kubelet's host machine and then exposed to the + pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. TODO: how do we prevent errors in the + filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs and + lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for + this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends + on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra + command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if no + secret object is specified. If the secret object contains + more than one secret, all secrets are passed to the plugin + scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to + a kubelet's host machine. This depends on the Flocker control + service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored as + metadata -> name on the dataset for Flocker should be + considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This + is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume that + you want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource in + GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an InitContainer + that clones the repo using git, then mount the EmptyDir into + the Pod''s container.' + properties: + directory: + description: directory is the target directory name. Must + not contain or start with '..'. If '.' is supplied, the + volume directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More info: + https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs volume + to be mounted with read-only permissions. Defaults to + false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or directory + on the host machine that is directly exposed to the container. + This is generally used for system agents or other privileged + things that are allowed to see the host machine. Most containers + will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host directory + mounts and who can/can not mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. If the + path is a symlink, it will follow the link to the real + path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that is + attached to a kubelet''s host machine and then exposed to + the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that uses + an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. The + portal is either an IP or ip_addr:port if the port is + other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target + and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: targetPortal is iSCSI Target Portal. The Portal + is either an IP or ip_addr:port if the port is other than + default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and unique + within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that shares + a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. More + info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export to + be mounted with read-only permissions. Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of the + NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents a + reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting in + VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set permissions + on created files by default. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path are + not affected by this setting. This might be in conflict + with other options that affect the file mode, like fsGroup, + and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with + other supported volume types + properties: + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the ConfigMap, the volume + setup will error unless it is marked optional. + Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be + an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML + accepts both octal and decimal values, + JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the file + mode, like fsGroup, and the result can + be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu + and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data + to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the Secret, the volume setup + will error unless it is marked optional. Paths + must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional field specify whether the + Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about + the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience + of the token. A recipient of a token must identify + itself with an identifier specified in the audience + of the token, and otherwise should reject the + token. The audience defaults to the identifier + of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, the + kubelet volume plugin will proactively rotate + the service account token. The kubelet will + start trying to rotate the token if the token + is older than 80 percent of its time to live + or if the token is older than 24 hours.Defaults + to 1 hour and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to the + mount point of the file to project the token + into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is no + group + type: string + readOnly: + description: readOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults to + false. + type: boolean + registry: + description: registry represents a single or multiple Quobyte + Registry services specified as a string as host:port pair + (multiple entries are separated with commas) which acts + as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume in the + Backend Used with dynamically provisioned Quobyte volumes, + value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to serivceaccount + user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication secret + for RBDUser. If provided overrides keyring. Default is + nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is the rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for ScaleIO + user and other sensitive information. If this is not provided, + Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage for + a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: system is the name of the storage system as + configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for obtaining + the StorageOS API credentials. If not specified, default + values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: volumeName is the human-readable name of the + StorageOS volume. Volume names are only unique within + a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of the + volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS + for tighter integration. Set VolumeName to any name to + override the default behaviour. Set to "default" if you + are not using namespaces within StorageOS. Namespaces + that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere + volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - connectorContainers + - size + - volumes + type: object + status: + description: ConnectorsStatus defines the observed state of ConnectorsStatus + properties: + nodes: + items: + type: string + type: array + size: + type: integer + required: + - nodes + - size + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/eventmesh-operator/config/crd/bases/eventmesh-operator.eventmesh_runtimes.yaml b/eventmesh-operator/config/crd/bases/eventmesh-operator.eventmesh_runtimes.yaml new file mode 100644 index 0000000000..b56d1a55f4 --- /dev/null +++ b/eventmesh-operator/config/crd/bases/eventmesh-operator.eventmesh_runtimes.yaml @@ -0,0 +1,8158 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: runtimes.eventmesh-operator.eventmesh +spec: + group: eventmesh-operator.eventmesh + names: + kind: Runtime + listKind: RuntimeList + plural: runtimes + singular: runtime + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Runtime is the Schema for the Runtime API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: RuntimeSpec defines the desired state of Runtime + properties: + allowRestart: + description: AllowRestart defines whether allow pod restart + type: boolean + containerSecurityContext: + description: ContainerSecurityContext Container Security Context + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process + can gain more privileges than its parent process. This bool + directly controls if the no_new_privs flag will be set on the + container process. AllowPrivilegeEscalation is true always when + the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container + runtime. Note that this field cannot be set when spec.os.name + is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged + containers are essentially equivalent to root on the host. Defaults + to false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for + the containers. The default is DefaultProcMount which uses the + container runtime defaults for readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. + Default is false. Note that this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence. Note that this + field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If + seccomp options are provided at both the pod & container level, + the container options override the pod options. Note that this + field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will + be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is alpha-level + and will only be honored by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature flag + will result in errors when validating the Pod. All of a + Pod's containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + replicaPerGroup: + description: ReplicaPerGroup each runtime's replica number + type: integer + runtimePodTemplate: + description: RuntimePodTemplate define some configuration + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource + this object represents. Servers may infer this from the endpoint + the client submits requests to. Cannot be updated. In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + template: + description: Template defines the pods that will be created from + this pod template. https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + properties: + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + type: object + spec: + description: 'Specification of the desired behavior of the + pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' + properties: + activeDeadlineSeconds: + description: Optional duration in seconds the pod may + be active on the node relative to StartTime before the + system will actively try to mark it failed and kill + associated containers. Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a + node that violates one or more of the expressions. + The node that is most preferred is the one with + the greatest sum of weights, i.e. for each node + that meets all of the scheduling requirements + (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by + iterating through the elements of this field + and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) + with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 + (i.e. it's a no-op). A null preferred scheduling + term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: Represents a key's + relationship to a set of values. + Valid operators are In, NotIn, + Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string + values. If the operator is In + or NotIn, the values array must + be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + If the operator is Gt or Lt, + the values array must have a + single element, which will be + interpreted as an integer. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: Represents a key's + relationship to a set of values. + Valid operators are In, NotIn, + Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string + values. If the operator is In + or NotIn, the values array must + be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + If the operator is Gt or Lt, + the values array must have a + single element, which will be + interpreted as an integer. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in + the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, + the pod will not be scheduled onto the node. + If the affinity requirements specified by this + field cease to be met at some point during pod + execution (e.g. due to an update), the system + may or may not try to eventually evict the pod + from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector + term matches no objects. The requirements + of them are ANDed. The TopologySelectorTerm + type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector + requirements by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: Represents a key's + relationship to a set of values. + Valid operators are In, NotIn, + Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string + values. If the operator is In + or NotIn, the values array must + be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + If the operator is Gt or Lt, + the values array must have a + single element, which will be + interpreted as an integer. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector + requirements by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that + the selector applies to. + type: string + operator: + description: Represents a key's + relationship to a set of values. + Valid operators are In, NotIn, + Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string + values. If the operator is In + or NotIn, the values array must + be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + If the operator is Gt or Lt, + the values array must have a + single element, which will be + interpreted as an integer. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules + (e.g. co-locate this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a + node that violates one or more of the expressions. + The node that is most preferred is the one with + the greatest sum of weights, i.e. for each node + that meets all of the scheduling requirements + (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by + iterating through the elements of this field + and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; + the node(s) with the highest sum are the most + preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set + of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector + requirement is a selector that + contains values, a key, and + an operator that relates the + key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to + a set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an + array of string values. + If the operator is In or + NotIn, the values array + must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be + empty. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single + {key,value} in the matchLabels + map is equivalent to an element + of matchExpressions, whose key + field is "key", the operator is + "In", and the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the + set of namespaces that the term applies + to. The term is applied to the union + of the namespaces selected by this + field and the ones listed in the namespaces + field. null selector and null or empty + namespaces list means "this pod's + namespace". An empty selector ({}) + matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector + requirement is a selector that + contains values, a key, and + an operator that relates the + key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to + a set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an + array of string values. + If the operator is In or + NotIn, the values array + must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be + empty. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single + {key,value} in the matchLabels + map is equivalent to an element + of matchExpressions, whose key + field is "key", the operator is + "In", and the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a + static list of namespace names that + the term applies to. The term is applied + to the union of the namespaces listed + in this field and the ones selected + by namespaceSelector. null or empty + namespaces list and null namespaceSelector + means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where + co-located is defined as running on + a node whose value of the label with + key topologyKey matches that of any + node on which any of the selected + pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in + the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, + the pod will not be scheduled onto the node. + If the affinity requirements specified by this + field cease to be met at some point during pod + execution (e.g. due to a pod label update), + the system may or may not try to eventually + evict the pod from its node. When there are + multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the + given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) + with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on + which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set + of namespaces that the term applies to. + The term is applied to the union of the + namespaces selected by this field and + the ones listed in the namespaces field. + null selector and null or empty namespaces + list means "this pod's namespace". An + empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling + rules (e.g. avoid putting this pod in the same node, + zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity + expressions specified by this field, but it + may choose a node that violates one or more + of the expressions. The node that is most preferred + is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a + sum by iterating through the elements of this + field and adding "weight" to the sum if the + node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest + sum are the most preferred. + items: + description: The weights of all of the matched + WeightedPodAffinityTerm fields are added per-node + to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set + of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector + requirement is a selector that + contains values, a key, and + an operator that relates the + key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to + a set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an + array of string values. + If the operator is In or + NotIn, the values array + must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be + empty. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single + {key,value} in the matchLabels + map is equivalent to an element + of matchExpressions, whose key + field is "key", the operator is + "In", and the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the + set of namespaces that the term applies + to. The term is applied to the union + of the namespaces selected by this + field and the ones listed in the namespaces + field. null selector and null or empty + namespaces list means "this pod's + namespace". An empty selector ({}) + matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector + requirement is a selector that + contains values, a key, and + an operator that relates the + key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to + a set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an + array of string values. + If the operator is In or + NotIn, the values array + must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be + empty. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single + {key,value} in the matchLabels + map is equivalent to an element + of matchExpressions, whose key + field is "key", the operator is + "In", and the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a + static list of namespace names that + the term applies to. The term is applied + to the union of the namespaces listed + in this field and the ones selected + by namespaceSelector. null or empty + namespaces list and null namespaceSelector + means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where + co-located is defined as running on + a node whose value of the label with + key topologyKey matches that of any + node on which any of the selected + pods is running. Empty topologyKey + is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in + the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements + specified by this field are not met at scheduling + time, the pod will not be scheduled onto the + node. If the anti-affinity requirements specified + by this field cease to be met at some point + during pod execution (e.g. due to a pod label + update), the system may or may not try to eventually + evict the pod from its node. When there are + multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the + given namespace(s)) that this pod should be + co-located (affinity) or not co-located (anti-affinity) + with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on + which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set + of namespaces that the term applies to. + The term is applied to the union of the + namespaces selected by this field and + the ones listed in the namespaces field. + null selector and null or empty namespaces + list means "this pod's namespace". An + empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static + list of namespace names that the term + applies to. The term is applied to the + union of the namespaces listed in this + field and the ones selected by namespaceSelector. + null or empty namespaces list and null + namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether + a service account token should be automatically mounted. + type: boolean + containers: + description: List of containers belonging to the pod. + Containers cannot currently be added or removed. There + must be at least one container in a Pod. Cannot be updated. + items: + description: A single application container that you + want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using + the container''s environment. If a variable cannot + be resolved, the reference in the input string + will be unchanged. Double $$ are reduced to a + single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will + never be expanded, regardless of whether the variable + exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within + a shell. The container image''s ENTRYPOINT is + used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, + the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set + in the container. Cannot be updated. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previously defined + environment variables in the container and + any service environment variables. If a + variable cannot be resolved, the reference + in the input string will be unchanged. Double + $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable + exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and + requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment + variables in the container. The keys defined within + a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container + is starting. When a key exists in multiple sources, + the value associated with the last source will + take precedence. Values defined by an Env with + a duplicate key will take precedence. Cannot be + updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a + C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config + management to default or override container images + in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, + Never, IfNotPresent. Defaults to Always if :latest + tag is specified, or IfNotPresent otherwise. Cannot + be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system + should take in response to container lifecycle + events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately + after a container is created. If the handler + fails, the container is terminated and restarted + according to its restart policy. Other management + of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT + supported as a LifecycleHandler and kept + for the backward compatibility. There + are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler + is specified. + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately + before a container is terminated due to an + API request or management event such as liveness/startup + probe failure, preemption, resource contention, + etc. The handler is not called if the container + crashes or exits. The Pod''s termination grace + period countdown begins before the PreStop + hook is executed. Regardless of the outcome + of the handler, the container will eventually + terminate within the Pod''s termination grace + period (unless delayed by finalizers). Other + management of the container blocks until the + hook completes or until the termination grace + period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT + supported as a LifecycleHandler and kept + for the backward compatibility. There + are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler + is specified. + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. This is a beta field and requires + enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the + service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default + behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the + pod needs to terminate gracefully upon probe + failure. The grace period is the duration + in seconds after the processes running in + the pod are sent a termination signal and + the time when the processes are forcibly halted + with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides + the value provided by the pod spec. Value + must be non-negative integer. The value zero + indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta + field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which + the probe times out. Defaults to 1 second. + Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as + a DNS_LABEL. Each container in a pod must have + a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Not specifying a port here DOES NOT prevent that + port from being exposed. Any port which is listening + on the default "0.0.0.0" address inside a container + will be accessible from the network. Modifying + this array with strategic merge patch may corrupt + the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: Number of port to expose on the + pod's IP address. This must be a valid port + number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: Number of port to expose on the + host. If specified, this must be a valid + port number, 0 < x < 65536. If HostNetwork + is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an + IANA_SVC_NAME and unique within the pod. + Each named port in a pod must have a unique + name. Name for the port that can be referred + to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, + TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service + readiness. Container will be removed from service + endpoints if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. This is a beta field and requires + enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the + service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default + behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the + pod needs to terminate gracefully upon probe + failure. The grace period is the duration + in seconds after the processes running in + the pod are sent a termination signal and + the time when the processes are forcibly halted + with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides + the value provided by the pod spec. Value + must be non-negative integer. The value zero + indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta + field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which + the probe times out. Defaults to 1 second. + Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this + container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, + defined in spec.resourceClaims, that are used + by this container. \n This is an alpha field + and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable." + items: + description: ResourceClaim references one + entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available inside + a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. If Requests + is omitted for a container, it defaults to + Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security + options the container should be run with. If set, + the fields of SecurityContext override the equivalent + fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls + whether a process can gain more privileges + than its parent process. This bool directly + controls if the no_new_privs flag will be + set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run + as Privileged 2) has CAP_SYS_ADMIN Note that + this field cannot be set when spec.os.name + is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when + running containers. Defaults to the default + set of capabilities granted by the container + runtime. Note that this field cannot be set + when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. + Processes in privileged containers are essentially + equivalent to root on the host. Defaults to + false. Note that this field cannot be set + when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc + mount to use for the containers. The default + is DefaultProcMount which uses the container + runtime defaults for readonly paths and masked + paths. This requires the ProcMountType feature + flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that + this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of + the container process. Uses runtime default + if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. Note that this field cannot be + set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must + run as a non-root user. If true, the Kubelet + will validate the image at runtime to ensure + that it does not run as UID 0 (root) and fail + to start the container if it does. If unset + or false, no such validation will be performed. + May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of + the container process. Defaults to user specified + in image metadata if unspecified. May also + be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied + to the container. If unspecified, the container + runtime will allocate a random SELinux context + for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. Note that this field cannot be + set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this + container. If seccomp options are provided + at both the pod & container level, the container + options override the pod options. Note that + this field cannot be set when spec.os.name + is windows. + properties: + localhostProfile: + description: localhostProfile indicates + a profile defined in a file on the node + should be used. The profile must be preconfigured + on the node to work. Must be a descending + path, relative to the kubelet's configured + seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind + of seccomp profile will be applied. Valid + options are: \n Localhost - a profile + defined in a file on the node should be + used. RuntimeDefault - the container runtime + default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options + from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. Note that this field cannot be + set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where + the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName + field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a + container should be run as a 'Host Process' + container. This field is alpha-level and + will only be honored by components that + enable the WindowsHostProcessContainers + feature flag. Setting this field without + the feature flag will result in errors + when validating the Pod. All of a Pod's + containers must have the same effective + HostProcess value (it is not allowed to + have a mix of HostProcess containers and + non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to + run the entrypoint of the container process. + Defaults to the user specified in image + metadata if unspecified. May also be set + in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, + the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod + has successfully initialized. If specified, no + other probes are executed until this completes + successfully. If this probe fails, the Pod will + be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it + might take a long time to load data or warm a + cache, than during steady-state operation. This + cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. This is a beta field and requires + enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the + service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default + behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the + pod needs to terminate gracefully upon probe + failure. The grace period is the duration + in seconds after the processes running in + the pod are sent a termination signal and + the time when the processes are forcibly halted + with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides + the value provided by the pod spec. Value + must be non-negative integer. The value zero + indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta + field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which + the probe times out. Defaults to 1 second. + Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate + a buffer for stdin in the container runtime. If + this is not set, reads from stdin in the container + will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should + close the stdin channel after it has been opened + by a single attach. When stdin is true the stdin + stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is + opened on container start, is empty until the + first client attaches to stdin, and then remains + open and accepts data until the client disconnects, + at which time stdin is closed and remains closed + until the container is restarted. If this flag + is false, a container processes that reads from + stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to + which the container''s termination message will + be written is mounted into the container''s filesystem. + Message written is intended to be brief final + status, such as an assertion failure message. + Will be truncated by the node if greater than + 4096 bytes. The total message length across all + containers will be limited to 12kb. Defaults to + /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message + should be populated. File will use the contents + of terminationMessagePath to populate the container + status message on both success and failure. FallbackToLogsOnError + will use the last chunk of container log output + if the termination message file is empty and the + container exited with an error. The log output + is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate + a TTY for itself, also requires 'stdin' to be + true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block + devices to be used by the container. + items: + description: volumeDevice describes a mapping + of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside + of the container that the device will be + mapped to. + type: string + name: + description: name must match the name of a + persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting + of a Volume within a container. + properties: + mountPath: + description: Path within the container at + which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how + mounts are propagated from the host to container + and the other way around. When not set, + MountPropagationNone is used. This field + is beta in 1.10. + type: string + name: + description: This must match the Name of a + Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults + to false. + type: boolean + subPath: + description: Path within the volume from which + the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume + from which the container's volume should + be mounted. Behaves similarly to SubPath + but environment variable references $(VAR_NAME) + are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not + specified, the container runtime's default will + be used, which might be configured in the container + image. Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: Specifies the DNS parameters of a pod. Parameters + specified here will be merged to the generated DNS configuration + based on DNSPolicy. + properties: + nameservers: + description: A list of DNS name server IP addresses. + This will be appended to the base nameservers generated + from DNSPolicy. Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: A list of DNS resolver options. This + will be merged with the base options generated from + DNSPolicy. Duplicated entries will be removed. Resolution + options given in Options will override those that + appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver + options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: A list of DNS search domains for host-name + lookup. This will be appended to the base search + paths generated from DNSPolicy. Duplicated search + paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: Set DNS policy for the pod. Defaults to "ClusterFirst". + Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', + 'Default' or 'None'. DNS parameters given in DNSConfig + will be merged with the policy selected with DNSPolicy. + To have DNS options set along with hostNetwork, you + have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: 'EnableServiceLinks indicates whether information + about services should be injected into pod''s environment + variables, matching the syntax of Docker links. Optional: + Defaults to true.' + type: boolean + ephemeralContainers: + description: List of ephemeral containers run in this + pod. Ephemeral containers may be run in an existing + pod to perform user-initiated actions such as debugging. + This list cannot be specified when creating a pod, and + it cannot be modified by updating the pod spec. In order + to add an ephemeral container to an existing pod, use + the pod's ephemeralcontainers subresource. + items: + description: "An EphemeralContainer is a temporary container + that you may add to an existing Pod for user-initiated + activities such as debugging. Ephemeral containers + have no resource or scheduling guarantees, and they + will not be restarted when they exit or when a Pod + is removed or restarted. The kubelet may evict a Pod + if an ephemeral container causes the Pod to exceed + its resource allocation. \n To add an ephemeral container, + use the ephemeralcontainers subresource of an existing + Pod. Ephemeral containers may not be removed or restarted." + properties: + args: + description: 'Arguments to the entrypoint. The image''s + CMD is used if this is not provided. Variable + references $(VAR_NAME) are expanded using the + container''s environment. If a variable cannot + be resolved, the reference in the input string + will be unchanged. Double $$ are reduced to a + single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will + never be expanded, regardless of whether the variable + exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within + a shell. The image''s ENTRYPOINT is used if this + is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. + If a variable cannot be resolved, the reference + in the input string will be unchanged. Double + $$ are reduced to a single $, which allows for + escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set + in the container. Cannot be updated. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previously defined + environment variables in the container and + any service environment variables. If a + variable cannot be resolved, the reference + in the input string will be unchanged. Double + $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable + exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and + requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment + variables in the container. The keys defined within + a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container + is starting. When a key exists in multiple sources, + the value associated with the last source will + take precedence. Values defined by an Env with + a duplicate key will take precedence. Cannot be + updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a + C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, + Never, IfNotPresent. Defaults to Always if :latest + tag is specified, or IfNotPresent otherwise. Cannot + be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral + containers. + properties: + postStart: + description: 'PostStart is called immediately + after a container is created. If the handler + fails, the container is terminated and restarted + according to its restart policy. Other management + of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT + supported as a LifecycleHandler and kept + for the backward compatibility. There + are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler + is specified. + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately + before a container is terminated due to an + API request or management event such as liveness/startup + probe failure, preemption, resource contention, + etc. The handler is not called if the container + crashes or exits. The Pod''s termination grace + period countdown begins before the PreStop + hook is executed. Regardless of the outcome + of the handler, the container will eventually + terminate within the Pod''s termination grace + period (unless delayed by finalizers). Other + management of the container blocks until the + hook completes or until the termination grace + period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT + supported as a LifecycleHandler and kept + for the backward compatibility. There + are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler + is specified. + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. This is a beta field and requires + enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the + service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default + behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the + pod needs to terminate gracefully upon probe + failure. The grace period is the duration + in seconds after the processes running in + the pod are sent a termination signal and + the time when the processes are forcibly halted + with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides + the value provided by the pod spec. Value + must be non-negative integer. The value zero + indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta + field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which + the probe times out. Defaults to 1 second. + Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the ephemeral container specified + as a DNS_LABEL. This name must be unique among + all containers, init containers and ephemeral + containers. + type: string + ports: + description: Ports are not allowed for ephemeral + containers. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: Number of port to expose on the + pod's IP address. This must be a valid port + number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: Number of port to expose on the + host. If specified, this must be a valid + port number, 0 < x < 65536. If HostNetwork + is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an + IANA_SVC_NAME and unique within the pod. + Each named port in a pod must have a unique + name. Name for the port that can be referred + to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, + TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. This is a beta field and requires + enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the + service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default + behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the + pod needs to terminate gracefully upon probe + failure. The grace period is the duration + in seconds after the processes running in + the pod are sent a termination signal and + the time when the processes are forcibly halted + with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides + the value provided by the pod spec. Value + must be non-negative integer. The value zero + indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta + field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which + the probe times out. Defaults to 1 second. + Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: Resources are not allowed for ephemeral + containers. Ephemeral containers use spare resources + already allocated to the pod. + properties: + claims: + description: "Claims lists the names of resources, + defined in spec.resourceClaims, that are used + by this container. \n This is an alpha field + and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable." + items: + description: ResourceClaim references one + entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available inside + a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. If Requests + is omitted for a container, it defaults to + Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'Optional: SecurityContext defines + the security options the ephemeral container should + be run with. If set, the fields of SecurityContext + override the equivalent fields of PodSecurityContext.' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls + whether a process can gain more privileges + than its parent process. This bool directly + controls if the no_new_privs flag will be + set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run + as Privileged 2) has CAP_SYS_ADMIN Note that + this field cannot be set when spec.os.name + is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when + running containers. Defaults to the default + set of capabilities granted by the container + runtime. Note that this field cannot be set + when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. + Processes in privileged containers are essentially + equivalent to root on the host. Defaults to + false. Note that this field cannot be set + when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc + mount to use for the containers. The default + is DefaultProcMount which uses the container + runtime defaults for readonly paths and masked + paths. This requires the ProcMountType feature + flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that + this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of + the container process. Uses runtime default + if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. Note that this field cannot be + set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must + run as a non-root user. If true, the Kubelet + will validate the image at runtime to ensure + that it does not run as UID 0 (root) and fail + to start the container if it does. If unset + or false, no such validation will be performed. + May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of + the container process. Defaults to user specified + in image metadata if unspecified. May also + be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied + to the container. If unspecified, the container + runtime will allocate a random SELinux context + for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. Note that this field cannot be + set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this + container. If seccomp options are provided + at both the pod & container level, the container + options override the pod options. Note that + this field cannot be set when spec.os.name + is windows. + properties: + localhostProfile: + description: localhostProfile indicates + a profile defined in a file on the node + should be used. The profile must be preconfigured + on the node to work. Must be a descending + path, relative to the kubelet's configured + seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind + of seccomp profile will be applied. Valid + options are: \n Localhost - a profile + defined in a file on the node should be + used. RuntimeDefault - the container runtime + default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options + from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. Note that this field cannot be + set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where + the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName + field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a + container should be run as a 'Host Process' + container. This field is alpha-level and + will only be honored by components that + enable the WindowsHostProcessContainers + feature flag. Setting this field without + the feature flag will result in errors + when validating the Pod. All of a Pod's + containers must have the same effective + HostProcess value (it is not allowed to + have a mix of HostProcess containers and + non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to + run the entrypoint of the container process. + Defaults to the user specified in image + metadata if unspecified. May also be set + in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, + the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral + containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. This is a beta field and requires + enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the + service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default + behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the + pod needs to terminate gracefully upon probe + failure. The grace period is the duration + in seconds after the processes running in + the pod are sent a termination signal and + the time when the processes are forcibly halted + with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides + the value provided by the pod spec. Value + must be non-negative integer. The value zero + indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta + field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which + the probe times out. Defaults to 1 second. + Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate + a buffer for stdin in the container runtime. If + this is not set, reads from stdin in the container + will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should + close the stdin channel after it has been opened + by a single attach. When stdin is true the stdin + stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is + opened on container start, is empty until the + first client attaches to stdin, and then remains + open and accepts data until the client disconnects, + at which time stdin is closed and remains closed + until the container is restarted. If this flag + is false, a container processes that reads from + stdin will never receive an EOF. Default is false + type: boolean + targetContainerName: + description: "If set, the name of the container + from PodSpec that this ephemeral container targets. + The ephemeral container will be run in the namespaces + (IPC, PID, etc) of this container. If not set + then the ephemeral container uses the namespaces + configured in the Pod spec. \n The container runtime + must implement support for this feature. If the + runtime does not support namespace targeting then + the result of setting this field is undefined." + type: string + terminationMessagePath: + description: 'Optional: Path at which the file to + which the container''s termination message will + be written is mounted into the container''s filesystem. + Message written is intended to be brief final + status, such as an assertion failure message. + Will be truncated by the node if greater than + 4096 bytes. The total message length across all + containers will be limited to 12kb. Defaults to + /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message + should be populated. File will use the contents + of terminationMessagePath to populate the container + status message on both success and failure. FallbackToLogsOnError + will use the last chunk of container log output + if the termination message file is empty and the + container exited with an error. The log output + is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate + a TTY for itself, also requires 'stdin' to be + true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block + devices to be used by the container. + items: + description: volumeDevice describes a mapping + of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside + of the container that the device will be + mapped to. + type: string + name: + description: name must match the name of a + persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Subpath mounts are not allowed for + ephemeral containers. Cannot be updated. + items: + description: VolumeMount describes a mounting + of a Volume within a container. + properties: + mountPath: + description: Path within the container at + which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how + mounts are propagated from the host to container + and the other way around. When not set, + MountPropagationNone is used. This field + is beta in 1.10. + type: string + name: + description: This must match the Name of a + Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults + to false. + type: boolean + subPath: + description: Path within the volume from which + the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume + from which the container's volume should + be mounted. Behaves similarly to SubPath + but environment variable references $(VAR_NAME) + are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not + specified, the container runtime's default will + be used, which might be configured in the container + image. Cannot be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: HostAliases is an optional list of hosts + and IPs that will be injected into the pod's hosts file + if specified. This is only valid for non-hostNetwork + pods. + items: + description: HostAlias holds the mapping between IP + and hostnames that will be injected as an entry in + the pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: 'Use the host''s ipc namespace. Optional: + Default to false.' + type: boolean + hostNetwork: + description: Host networking requested for this pod. Use + the host's network namespace. If this option is set, + the ports that will be used must be specified. Default + to false. + type: boolean + hostPID: + description: 'Use the host''s pid namespace. Optional: + Default to false.' + type: boolean + hostUsers: + description: 'Use the host''s user namespace. Optional: + Default to true. If set to true or not present, the + pod will be run in the host user namespace, useful for + when the pod needs a feature only available to the host + user namespace, such as loading a kernel module with + CAP_SYS_MODULE. When set to false, a new userns is created + for the pod. Setting false is useful for mitigating + container breakout vulnerabilities even allowing users + to run their containers as root without actually having + root privileges on the host. This field is alpha-level + and is only honored by servers that enable the UserNamespacesSupport + feature.' + type: boolean + hostname: + description: Specifies the hostname of the Pod If not + specified, the pod's hostname will be set to a system-defined + value. + type: string + imagePullSecrets: + description: 'ImagePullSecrets is an optional list of + references to secrets in the same namespace to use for + pulling any of the images used by this PodSpec. If specified, + these secrets will be passed to individual puller implementations + for them to use. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod' + items: + description: LocalObjectReference contains enough information + to let you locate the referenced object inside the + same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: 'List of initialization containers belonging + to the pod. Init containers are executed in order prior + to containers being started. If any init container fails, + the pod is considered to have failed and is handled + according to its restartPolicy. The name for an init + container or normal container must be unique among all + containers. Init containers may not have Lifecycle actions, + Readiness probes, Liveness probes, or Startup probes. + The resourceRequirements of an init container are taken + into account during scheduling by finding the highest + request/limit for each resource type, and then using + the max of of that value or the sum of the normal containers. + Limits are applied to init containers in a similar fashion. + Init containers cannot currently be added or removed. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/' + items: + description: A single application container that you + want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container + image''s CMD is used if this is not provided. + Variable references $(VAR_NAME) are expanded using + the container''s environment. If a variable cannot + be resolved, the reference in the input string + will be unchanged. Double $$ are reduced to a + single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will + never be expanded, regardless of whether the variable + exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within + a shell. The container image''s ENTRYPOINT is + used if this is not provided. Variable references + $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, + the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" + will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Cannot + be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set + in the container. Cannot be updated. + items: + description: EnvVar represents an environment + variable present in a Container. + properties: + name: + description: Name of the environment variable. + Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) + are expanded using the previously defined + environment variables in the container and + any service environment variables. If a + variable cannot be resolved, the reference + in the input string will be unchanged. Double + $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal + "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable + exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's + value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: + supports metadata.name, metadata.namespace, + `metadata.labels['''']`, `metadata.annotations['''']`, + spec.nodeName, spec.serviceAccountName, + status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and + requests (limits.cpu, limits.memory, + limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret + in the pod's namespace + properties: + key: + description: The key of the secret + to select from. Must be a valid + secret key. + type: string + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment + variables in the container. The keys defined within + a source must be a C_IDENTIFIER. All invalid keys + will be reported as an event when the container + is starting. When a key exists in multiple sources, + the value associated with the last source will + take precedence. Values defined by an Env with + a duplicate key will take precedence. Cannot be + updated. + items: + description: EnvFromSource represents the source + of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend + to each key in the ConfigMap. Must be a + C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret + must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config + management to default or override container images + in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, + Never, IfNotPresent. Defaults to Always if :latest + tag is specified, or IfNotPresent otherwise. Cannot + be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system + should take in response to container lifecycle + events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately + after a container is created. If the handler + fails, the container is terminated and restarted + according to its restart policy. Other management + of the container blocks until the hook completes. + More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT + supported as a LifecycleHandler and kept + for the backward compatibility. There + are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler + is specified. + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately + before a container is terminated due to an + API request or management event such as liveness/startup + probe failure, preemption, resource contention, + etc. The handler is not called if the container + crashes or exits. The Pod''s termination grace + period countdown begins before the PreStop + hook is executed. Regardless of the outcome + of the handler, the container will eventually + terminate within the Pod''s termination grace + period (unless delayed by finalizers). Other + management of the container blocks until the + hook completes or until the termination grace + period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to + take. + properties: + command: + description: Command is the command + line to execute inside the container, + the working directory for the command is + root ('/') in the container's filesystem. + The command is simply exec'd, it is + not run inside a shell, so traditional + shell instructions ('|', etc) won't + work. To use a shell, you need to + explicitly call out to that shell. + Exit status of 0 is treated as live/healthy + and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http + request to perform. + properties: + host: + description: Host name to connect to, + defaults to the pod IP. You probably + want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in + the request. HTTP allows repeated + headers. + items: + description: HTTPHeader describes + a custom header to be used in HTTP + probes + properties: + name: + description: The header field + name + type: string + value: + description: The header field + value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT + supported as a LifecycleHandler and kept + for the backward compatibility. There + are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler + is specified. + properties: + host: + description: 'Optional: Host name to + connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number + must be in the range 1 to 65535. Name + must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. + Container will be restarted if the probe fails. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. This is a beta field and requires + enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the + service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default + behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the + pod needs to terminate gracefully upon probe + failure. The grace period is the duration + in seconds after the processes running in + the pod are sent a termination signal and + the time when the processes are forcibly halted + with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides + the value provided by the pod spec. Value + must be non-negative integer. The value zero + indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta + field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which + the probe times out. Defaults to 1 second. + Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as + a DNS_LABEL. Each container in a pod must have + a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. + Not specifying a port here DOES NOT prevent that + port from being exposed. Any port which is listening + on the default "0.0.0.0" address inside a container + will be accessible from the network. Modifying + this array with strategic merge patch may corrupt + the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network + port in a single container. + properties: + containerPort: + description: Number of port to expose on the + pod's IP address. This must be a valid port + number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external + port to. + type: string + hostPort: + description: Number of port to expose on the + host. If specified, this must be a valid + port number, 0 < x < 65536. If HostNetwork + is specified, this must match ContainerPort. + Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an + IANA_SVC_NAME and unique within the pod. + Each named port in a pod must have a unique + name. Name for the port that can be referred + to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, + TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service + readiness. Container will be removed from service + endpoints if the probe fails. Cannot be updated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. This is a beta field and requires + enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the + service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default + behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the + pod needs to terminate gracefully upon probe + failure. The grace period is the duration + in seconds after the processes running in + the pod are sent a termination signal and + the time when the processes are forcibly halted + with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides + the value provided by the pod spec. Value + must be non-negative integer. The value zero + indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta + field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which + the probe times out. Defaults to 1 second. + Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this + container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, + defined in spec.resourceClaims, that are used + by this container. \n This is an alpha field + and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable." + items: + description: ResourceClaim references one + entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available inside + a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. If Requests + is omitted for a container, it defaults to + Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security + options the container should be run with. If set, + the fields of SecurityContext override the equivalent + fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls + whether a process can gain more privileges + than its parent process. This bool directly + controls if the no_new_privs flag will be + set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run + as Privileged 2) has CAP_SYS_ADMIN Note that + this field cannot be set when spec.os.name + is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when + running containers. Defaults to the default + set of capabilities granted by the container + runtime. Note that this field cannot be set + when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX + capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. + Processes in privileged containers are essentially + equivalent to root on the host. Defaults to + false. Note that this field cannot be set + when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc + mount to use for the containers. The default + is DefaultProcMount which uses the container + runtime defaults for readonly paths and masked + paths. This requires the ProcMountType feature + flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only + root filesystem. Default is false. Note that + this field cannot be set when spec.os.name + is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of + the container process. Uses runtime default + if unset. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. Note that this field cannot be + set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must + run as a non-root user. If true, the Kubelet + will validate the image at runtime to ensure + that it does not run as UID 0 (root) and fail + to start the container if it does. If unset + or false, no such validation will be performed. + May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of + the container process. Defaults to user specified + in image metadata if unspecified. May also + be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied + to the container. If unspecified, the container + runtime will allocate a random SELinux context + for each container. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. Note that this field cannot be + set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label + that applies to the container. + type: string + role: + description: Role is a SELinux role label + that applies to the container. + type: string + type: + description: Type is a SELinux type label + that applies to the container. + type: string + user: + description: User is a SELinux user label + that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this + container. If seccomp options are provided + at both the pod & container level, the container + options override the pod options. Note that + this field cannot be set when spec.os.name + is windows. + properties: + localhostProfile: + description: localhostProfile indicates + a profile defined in a file on the node + should be used. The profile must be preconfigured + on the node to work. Must be a descending + path, relative to the kubelet's configured + seccomp profile location. Must only be + set if type is "Localhost". + type: string + type: + description: "type indicates which kind + of seccomp profile will be applied. Valid + options are: \n Localhost - a profile + defined in a file on the node should be + used. RuntimeDefault - the container runtime + default profile should be used. Unconfined + - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options + from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. Note that this field cannot be + set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where + the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName + field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the + name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a + container should be run as a 'Host Process' + container. This field is alpha-level and + will only be honored by components that + enable the WindowsHostProcessContainers + feature flag. Setting this field without + the feature flag will result in errors + when validating the Pod. All of a Pod's + containers must have the same effective + HostProcess value (it is not allowed to + have a mix of HostProcess containers and + non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to + run the entrypoint of the container process. + Defaults to the user specified in image + metadata if unspecified. May also be set + in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, + the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod + has successfully initialized. If specified, no + other probes are executed until this completes + successfully. If this probe fails, the Pod will + be restarted, just as if the livenessProbe failed. + This can be used to provide different probe parameters + at the beginning of a Pod''s lifecycle, when it + might take a long time to load data or warm a + cache, than during steady-state operation. This + cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line + to execute inside the container, the working + directory for the command is root ('/') + in the container's filesystem. The command + is simply exec'd, it is not run inside + a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, + you need to explicitly call out to that + shell. Exit status of 0 is treated as + live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for + the probe to be considered failed after having + succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving + a GRPC port. This is a beta field and requires + enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. + Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the + service to place in the gRPC HealthCheckRequest + (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default + behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request + to perform. + properties: + host: + description: Host name to connect to, defaults + to the pod IP. You probably want to set + "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the + request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom + header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP + server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting + to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container + has started before liveness probes are initiated. + More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform + the probe. Default to 10 seconds. Minimum + value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for + the probe to be considered successful after + having failed. Defaults to 1. Must be 1 for + liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving + a TCP port. + properties: + host: + description: 'Optional: Host name to connect + to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port + to access on the container. Number must + be in the range 1 to 65535. Name must + be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the + pod needs to terminate gracefully upon probe + failure. The grace period is the duration + in seconds after the processes running in + the pod are sent a termination signal and + the time when the processes are forcibly halted + with a kill signal. Set this value longer + than the expected cleanup time for your process. + If this value is nil, the pod's terminationGracePeriodSeconds + will be used. Otherwise, this value overrides + the value provided by the pod spec. Value + must be non-negative integer. The value zero + indicates stop immediately via the kill signal + (no opportunity to shut down). This is a beta + field and requires enabling ProbeTerminationGracePeriod + feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds + is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which + the probe times out. Defaults to 1 second. + Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate + a buffer for stdin in the container runtime. If + this is not set, reads from stdin in the container + will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should + close the stdin channel after it has been opened + by a single attach. When stdin is true the stdin + stream will remain open across multiple attach + sessions. If stdinOnce is set to true, stdin is + opened on container start, is empty until the + first client attaches to stdin, and then remains + open and accepts data until the client disconnects, + at which time stdin is closed and remains closed + until the container is restarted. If this flag + is false, a container processes that reads from + stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to + which the container''s termination message will + be written is mounted into the container''s filesystem. + Message written is intended to be brief final + status, such as an assertion failure message. + Will be truncated by the node if greater than + 4096 bytes. The total message length across all + containers will be limited to 12kb. Defaults to + /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message + should be populated. File will use the contents + of terminationMessagePath to populate the container + status message on both success and failure. FallbackToLogsOnError + will use the last chunk of container log output + if the termination message file is empty and the + container exited with an error. The log output + is limited to 2048 bytes or 80 lines, whichever + is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate + a TTY for itself, also requires 'stdin' to be + true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block + devices to be used by the container. + items: + description: volumeDevice describes a mapping + of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside + of the container that the device will be + mapped to. + type: string + name: + description: name must match the name of a + persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's + filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting + of a Volume within a container. + properties: + mountPath: + description: Path within the container at + which the volume should be mounted. Must + not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how + mounts are propagated from the host to container + and the other way around. When not set, + MountPropagationNone is used. This field + is beta in 1.10. + type: string + name: + description: This must match the Name of a + Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write + otherwise (false or unspecified). Defaults + to false. + type: boolean + subPath: + description: Path within the volume from which + the container's volume should be mounted. + Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume + from which the container's volume should + be mounted. Behaves similarly to SubPath + but environment variable references $(VAR_NAME) + are expanded using the container's environment. + Defaults to "" (volume's root). SubPathExpr + and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not + specified, the container runtime's default will + be used, which might be configured in the container + image. Cannot be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: NodeName is a request to schedule this pod + onto a specific node. If it is non-empty, the scheduler + simply schedules this pod onto that node, assuming that + it fits resource requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: 'NodeSelector is a selector which must be + true for the pod to fit on a node. Selector which must + match a node''s labels for the pod to be scheduled on + that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + x-kubernetes-map-type: atomic + os: + description: "Specifies the OS of the containers in the + pod. Some pod and container fields are restricted if + this is set. \n If the OS field is set to linux, the + following fields must be unset: -securityContext.windowsOptions + \n If the OS field is set to windows, following fields + must be unset: - spec.hostPID - spec.hostIPC - spec.hostUsers + - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile + - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy + - spec.securityContext.sysctls - spec.shareProcessNamespace + - spec.securityContext.runAsUser - spec.securityContext.runAsGroup + - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions + - spec.containers[*].securityContext.seccompProfile + - spec.containers[*].securityContext.capabilities - + spec.containers[*].securityContext.readOnlyRootFilesystem + - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation + - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser + - spec.containers[*].securityContext.runAsGroup" + properties: + name: + description: 'Name is the name of the operating system. + The currently supported values are linux and windows. + Additional value may be defined in future and can + be one of: https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration + Clients should expect to handle additional values + and treat unrecognized values in this field as os: + null' + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Overhead represents the resource overhead + associated with running a pod for a given RuntimeClass. + This field will be autopopulated at admission time by + the RuntimeClass admission controller. If the RuntimeClass + admission controller is enabled, overhead must not be + set in Pod create requests. The RuntimeClass admission + controller will reject Pod create requests which have + the overhead already set. If RuntimeClass is configured + and selected in the PodSpec, Overhead will be set to + the value defined in the corresponding RuntimeClass, + otherwise it will remain unset and treated as zero. + More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md' + type: object + preemptionPolicy: + description: PreemptionPolicy is the Policy for preempting + pods with lower priority. One of Never, PreemptLowerPriority. + Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: The priority value. Various system components + use this field to find the priority of the pod. When + Priority Admission Controller is enabled, it prevents + users from setting this field. The admission controller + populates this field from PriorityClassName. The higher + the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: If specified, indicates the pod's priority. + "system-node-critical" and "system-cluster-critical" + are two special keywords which indicate the highest + priorities with the former being the highest priority. + Any other name must be defined by creating a PriorityClass + object with that name. If not specified, the pod priority + will be default or zero if there is no default. + type: string + readinessGates: + description: 'If specified, all readiness gates will be + evaluated for pod readiness. A pod is ready when all + its containers are ready AND all conditions specified + in the readiness gates have status equal to "True" More + info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates' + items: + description: PodReadinessGate contains the reference + to a pod condition + properties: + conditionType: + description: ConditionType refers to a condition + in the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + resourceClaims: + description: "ResourceClaims defines which ResourceClaims + must be allocated and reserved before the Pod is allowed + to start. The resources will be made available to those + containers which consume them by name. \n This is an + alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable." + items: + description: PodResourceClaim references exactly one + ResourceClaim through a ClaimSource. It adds a name + to it that uniquely identifies the ResourceClaim inside + the Pod. Containers that need access to the ResourceClaim + reference it with this name. + properties: + name: + description: Name uniquely identifies this resource + claim inside the pod. This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the + ResourceClaim. + properties: + resourceClaimName: + description: ResourceClaimName is the name of + a ResourceClaim object in the same namespace + as this pod. + type: string + resourceClaimTemplateName: + description: "ResourceClaimTemplateName is the + name of a ResourceClaimTemplate object in + the same namespace as this pod. \n The template + will be used to create a new ResourceClaim, + which will be bound to this pod. When this + pod is deleted, the ResourceClaim will also + be deleted. The name of the ResourceClaim + will be -, where + is the PodResourceClaim.Name. + Pod validation will reject the pod if the + concatenated name is not valid for a ResourceClaim + (e.g. too long). \n An existing ResourceClaim + with that name that is not owned by the pod + will not be used for the pod to avoid using + an unrelated resource by mistake. Scheduling + and pod startup are then blocked until the + unrelated ResourceClaim is removed. \n This + field is immutable and no changes will be + made to the corresponding ResourceClaim by + the control plane after creating the ResourceClaim." + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + description: 'Restart policy for all containers within + the pod. One of Always, OnFailure, Never. Default to + Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy' + type: string + runtimeClassName: + description: 'RuntimeClassName refers to a RuntimeClass + object in the node.k8s.io group, which should be used + to run this pod. If no RuntimeClass resource matches + the named class, the pod will not be run. If unset or + empty, the "legacy" RuntimeClass will be used, which + is an implicit class with an empty definition that uses + the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class' + type: string + schedulerName: + description: If specified, the pod will be dispatched + by specified scheduler. If not specified, the pod will + be dispatched by default scheduler. + type: string + schedulingGates: + description: "SchedulingGates is an opaque list of values + that if specified will block scheduling the pod. More + info: https://git.k8s.io/enhancements/keps/sig-scheduling/3521-pod-scheduling-readiness. + \n This is an alpha-level feature enabled by PodSchedulingReadiness + feature gate." + items: + description: PodSchedulingGate is associated to a Pod + to guard its scheduling. + properties: + name: + description: Name of the scheduling gate. Each scheduling + gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: 'SecurityContext holds pod-level security + attributes and common container settings. Optional: + Defaults to empty. See type description for default + values of each field.' + properties: + fsGroup: + description: "A special supplemental group that applies + to all containers in a pod. Some volume types allow + the Kubelet to change the ownership of that volume + to be owned by the pod: \n 1. The owning GID will + be the FSGroup 2. The setgid bit is set (new files + created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n + If unset, the Kubelet will not modify the ownership + and permissions of any volume. Note that this field + cannot be set when spec.os.name is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior + of changing ownership and permission of the volume + before being exposed inside Pod. This field will + only apply to volume types which support fsGroup + based ownership(and permissions). It will have no + effect on ephemeral volume types such as: secret, + configmaps and emptydir. Valid values are "OnRootMismatch" + and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name + is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the + container process. Uses runtime default if unset. + May also be set in SecurityContext. If set in both + SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for + that container. Note that this field cannot be set + when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run + as a non-root user. If true, the Kubelet will validate + the image at runtime to ensure that it does not + run as UID 0 (root) and fail to start the container + if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the + container process. Defaults to user specified in + image metadata if unspecified. May also be set in + SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this + field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to + all containers. If unspecified, the container runtime + will allocate a random SELinux context for each + container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence + for that container. Note that this field cannot + be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that + applies to the container. + type: string + role: + description: Role is a SELinux role label that + applies to the container. + type: string + type: + description: Type is a SELinux type label that + applies to the container. + type: string + user: + description: User is a SELinux user label that + applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers + in this pod. Note that this field cannot be set + when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile + defined in a file on the node should be used. + The profile must be preconfigured on the node + to work. Must be a descending path, relative + to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp + profile will be applied. Valid options are: + \n Localhost - a profile defined in a file on + the node should be used. RuntimeDefault - the + container runtime default profile should be + used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first + process run in each container, in addition to the + container's primary GID, the fsGroup (if specified), + and group memberships defined in the container image + for the uid of the container process. If unspecified, + no additional groups are added to any container. + Note that group memberships defined in the container + image for the uid of the container process are still + effective, even if they are not included in this + list. Note that this field cannot be set when spec.os.name + is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls + used for the pod. Pods with unsupported sysctls + (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name + is windows. + items: + description: Sysctl defines a kernel parameter to + be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied + to all containers. If unspecified, the options within + a container's SecurityContext will be used. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name + is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA + admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential + spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name + of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container + should be run as a 'Host Process' container. + This field is alpha-level and will only be honored + by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the + feature flag will result in errors when validating + the Pod. All of a Pod's containers must have + the same effective HostProcess value (it is + not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must + also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the + entrypoint of the container process. Defaults + to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set + in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes + precedence. + type: string + type: object + type: object + serviceAccount: + description: 'DeprecatedServiceAccount is a depreciated + alias for ServiceAccountName. Deprecated: Use serviceAccountName + instead.' + type: string + serviceAccountName: + description: 'ServiceAccountName is the name of the ServiceAccount + to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/' + type: string + setHostnameAsFQDN: + description: If true the pod's hostname will be configured + as the pod's FQDN, rather than the leaf name (the default). + In Linux containers, this means setting the FQDN in + the hostname field of the kernel (the nodename field + of struct utsname). In Windows containers, this means + setting the registry value of hostname for the registry + key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters + to FQDN. If a pod does not have FQDN, this has no effect. + Default to false. + type: boolean + shareProcessNamespace: + description: 'Share a single process namespace between + all of the containers in a pod. When this is set containers + will be able to view and signal processes from other + containers in the same pod, and the first process in + each container will not be assigned PID 1. HostPID and + ShareProcessNamespace cannot both be set. Optional: + Default to false.' + type: boolean + subdomain: + description: If specified, the fully qualified Pod hostname + will be "...svc.". If not specified, the pod will not have a + domainname at all. + type: string + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully. May be decreased in delete + request. Value must be non-negative integer. The value + zero indicates stop immediately via the kill signal + (no opportunity to shut down). If this value is nil, + the default grace period will be used instead. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and + the time when the processes are forcibly halted with + a kill signal. Set this value longer than the expected + cleanup time for your process. Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: The pod this Toleration is attached to + tolerates any taint that matches the triple + using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to + match. Empty means match all taint effects. When + specified, allowed values are NoSchedule, PreferNoSchedule + and NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. + If the key is empty, operator must be Exists; + this combination means to match all values and + all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints + of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect + NoExecute, otherwise this field is ignored) tolerates + the taint. By default, it is not set, which means + tolerate the taint forever (do not evict). Zero + and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value + should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: TopologySpreadConstraints describes how a + group of pods ought to spread across topology domains. + Scheduler will schedule pods in a way which abides by + the constraints. All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how + to spread matching pods among the given topology. + properties: + labelSelector: + description: LabelSelector is used to find matching + pods. Pods that match this label selector are + counted to determine the number of pods in their + corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: MatchLabelKeys is a set of pod label + keys to select the pods over which spreading will + be calculated. The keys are used to lookup values + from the incoming pod labels, those key-value + labels are ANDed with labelSelector to select + the group of existing pods over which spreading + will be calculated for the incoming pod. Keys + that don't exist in the incoming pod labels will + be ignored. A null or empty list means only match + against labelSelector. + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: 'MaxSkew describes the degree to which + pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, + it is the maximum permitted difference between + the number of matching pods in the target topology + and the global minimum. The global minimum is + the minimum number of matching pods in an eligible + domain or zero if the number of eligible domains + is less than MinDomains. For example, in a 3-zone + cluster, MaxSkew is set to 1, and pods with the + same labelSelector spread as 2/2/1: In this case, + the global minimum is 1. | zone1 | zone2 | zone3 + | | P P | P P | P | - if MaxSkew is 1, + incoming pod can only be scheduled to zone3 to + become 2/2/2; scheduling it onto zone1(zone2) + would make the ActualSkew(3-1) on zone1(zone2) + violate MaxSkew(1). - if MaxSkew is 2, incoming + pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, + it is used to give higher precedence to topologies + that satisfy it. It''s a required field. Default + value is 1 and 0 is not allowed.' + format: int32 + type: integer + minDomains: + description: "MinDomains indicates a minimum number + of eligible domains. When the number of eligible + domains with matching topology keys is less than + minDomains, Pod Topology Spread treats \"global + minimum\" as 0, and then the calculation of Skew + is performed. And when the number of eligible + domains with matching topology keys equals or + greater than minDomains, this value has no effect + on scheduling. As a result, when the number of + eligible domains is less than minDomains, scheduler + won't schedule more than maxSkew Pods to those + domains. If value is nil, the constraint behaves + as if MinDomains is equal to 1. Valid values are + integers greater than 0. When value is not nil, + WhenUnsatisfiable must be DoNotSchedule. \n For + example, in a 3-zone cluster, MaxSkew is set to + 2, MinDomains is set to 5 and pods with the same + labelSelector spread as 2/2/2: | zone1 | zone2 + | zone3 | | P P | P P | P P | The number + of domains is less than 5(MinDomains), so \"global + minimum\" is treated as 0. In this situation, + new pod with the same labelSelector cannot be + scheduled, because computed skew will be 3(3 - + 0) if new Pod is scheduled to any of the three + zones, it will violate MaxSkew. \n This is a beta + field and requires the MinDomainsInPodTopologySpread + feature gate to be enabled (enabled by default)." + format: int32 + type: integer + nodeAffinityPolicy: + description: "NodeAffinityPolicy indicates how we + will treat Pod's nodeAffinity/nodeSelector when + calculating pod topology spread skew. Options + are: - Honor: only nodes matching nodeAffinity/nodeSelector + are included in the calculations. - Ignore: nodeAffinity/nodeSelector + are ignored. All nodes are included in the calculations. + \n If this value is nil, the behavior is equivalent + to the Honor policy. This is a beta-level feature + default enabled by the NodeInclusionPolicyInPodTopologySpread + feature flag." + type: string + nodeTaintsPolicy: + description: "NodeTaintsPolicy indicates how we + will treat node taints when calculating pod topology + spread skew. Options are: - Honor: nodes without + taints, along with tainted nodes for which the + incoming pod has a toleration, are included. - + Ignore: node taints are ignored. All nodes are + included. \n If this value is nil, the behavior + is equivalent to the Ignore policy. This is a + beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread + feature flag." + type: string + topologyKey: + description: TopologyKey is the key of node labels. + Nodes that have a label with this key and identical + values are considered to be in the same topology. + We consider each as a "bucket", and + try to put balanced number of pods into each bucket. + We define a domain as a particular instance of + a topology. Also, we define an eligible domain + as a domain whose nodes meet the requirements + of nodeAffinityPolicy and nodeTaintsPolicy. e.g. + If TopologyKey is "kubernetes.io/hostname", each + Node is a domain of that topology. And, if TopologyKey + is "topology.kubernetes.io/zone", each zone is + a domain of that topology. It's a required field. + type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to + deal with a pod if it doesn''t satisfy the spread + constraint. - DoNotSchedule (default) tells the + scheduler not to schedule it. - ScheduleAnyway + tells the scheduler to schedule the pod in any + location, but giving higher precedence to topologies + that would help reduce the skew. A constraint + is considered "Unsatisfiable" for an incoming + pod if and only if every possible node assignment + for that pod would violate "MaxSkew" on some topology. + For example, in a 3-zone cluster, MaxSkew is set + to 1, and pods with the same labelSelector spread + as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | + If WhenUnsatisfiable is set to DoNotSchedule, + incoming pod can only be scheduled to zone2(zone3) + to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) + satisfies MaxSkew(1). In other words, the cluster + can still be imbalanced, but scheduler won''t + make it *more* imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: 'List of volumes that can be mounted by containers + belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes' + items: + description: Volume represents a named volume in a pod + that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an + AWS Disk resource that is attached to a kubelet''s + host machine and then exposed to the pod. More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type + of the volume that you want to mount. Tip: + Ensure that the filesystem type is supported + by the host operating system. Examples: "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in + the volume that you want to mount. If omitted, + the default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for + /dev/sda is "0" (or you can leave the property + empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force + the readOnly setting in VolumeMounts. More + info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent + disk resource in AWS (Amazon EBS volume). + More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data + Disk mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching + mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data + disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk + in the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. + Must be a filesystem type supported by the + host operating system. Ex. "ext4", "xfs", + "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + kind: + description: 'kind expected values are Shared: + multiple blob disks per storage account Dedicated: + single blob disk per storage account Managed: + azure managed data disk (only in managed availability + set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File + Service mount on the host and bind mount to the + pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret + that contains Azure Storage Account Name and + Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on + the host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors + is a collection of Ceph monitors More info: + https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the + mounted root, rather than the full Ceph tree, + default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults + to false (read/write). ReadOnly here will + force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile + is the path to key ring for User, default + is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef + is reference to the authentication secret + for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is optional: User is the + rados user name, default is admin More info: + https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume + attached and mounted on kubelets host machine. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type + to mount. Must be a filesystem type supported + by the host operating system. Examples: "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points + to a secret object containing parameters used + to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: 'volumeID used to identify the + volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that + should populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode + bits used to set permissions on created files + by default. Must be an octal value between + 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within + the path are not affected by this setting. + This might be in conflict with other options + that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified + which is not present in the ConfigMap, the + volume setup will error unless it is marked + optional. Paths must be relative and may not + contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 + and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, like + fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path + of the file to map the key to. May not + be an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents + ephemeral storage that is handled by certain external + CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver + that handles this volume. Consult with your + admin for the correct name as registered in + the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", + "ntfs". If not provided, the empty value is + passed to the associated CSI driver which + will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference + to the secret object containing sensitive + information to pass to the CSI driver to complete + the CSI NodePublishVolume and NodeUnpublishVolume + calls. This field is optional, and may be + empty if no secret is required. If the secret + object contains more than one secret, all + secret references are passed. + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: readOnly specifies a read-only + configuration for the volume. Defaults to + false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific + properties that are passed to the CSI driver. + Consult your driver's documentation for supported + values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API + about the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on + created files by default. Must be a Optional: + mode bits used to set permissions on created + files by default. Must be an octal value between + 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within + the path are not affected by this setting. + This might be in conflict with other options + that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API + volume file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema + the FieldPath is written in terms + of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to + select in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used + to set permissions on this file, must + be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. + YAML accepts both octal and decimal + values, JSON requires decimal values + for mode bits. If not specified, the + volume defaultMode will be used. This + might be in conflict with other options + that affect the file mode, like fsGroup, + and the result can be other mode bits + set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. + Must not be absolute or contain the + ''..'' path. Must be utf-8 encoded. + The first item of the relative path + must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and + requests (limits.cpu, limits.memory, + requests.cpu and requests.memory) are + currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output + format of the exposed resources, + defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory + that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of + storage medium should back this directory. + The default is "" which means to use the node''s + default medium. Must be an empty string (default) + or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount + of local storage required for this EmptyDir + volume. The size limit is also applicable + for memory medium. The maximum usage on memory + medium EmptyDir would be the minimum value + between the SizeLimit specified here and the + sum of memory limits of all containers in + a pod. The default is nil which means that + the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that + is handled by a cluster storage driver. The volume's + lifecycle is tied to the pod that defines it - + it will be created before the pod starts, and + deleted when the pod is removed. \n Use this if: + a) the volume is only needed while the pod runs, + b) features of normal volumes like restoring from + snapshot or capacity tracking are needed, c) the + storage driver is specified through a storage + class, and d) the storage driver supports dynamic + volume provisioning through a PersistentVolumeClaim + (see EphemeralVolumeSource for more information + on the connection between this volume type and + PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes + that persist for longer than the lifecycle of + an individual pod. \n Use CSI for light-weight + local ephemeral volumes if the CSI driver is meant + to be used that way - see the documentation of + the driver for more information. \n A pod can + use both types of ephemeral volumes and persistent + volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone + PVC to provision the volume. The pod in which + this EphemeralVolumeSource is embedded will + be the owner of the PVC, i.e. the PVC will + be deleted together with the pod. The name + of the PVC will be `-` + where `` is the name from the + `PodSpec.Volumes` array entry. Pod validation + will reject the pod if the concatenated name + is not valid for a PVC (for example, too long). + \n An existing PVC with that name that is + not owned by the pod will *not* be used for + the pod to avoid using an unrelated volume + by mistake. Starting the pod is then blocked + until the unrelated PVC is removed. If such + a pre-created PVC is meant to be used by the + pod, the PVC has to updated with an owner + reference to the pod once the pod exists. + Normally this should not be necessary, but + it may be useful when manually reconstructing + a broken cluster. \n This field is read-only + and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, + must not be nil." + properties: + metadata: + description: May contain labels and annotations + that will be copied into the PVC when + creating it. No other fields are allowed + and will be rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged + into the PVC that gets created from this + template. The same fields as in a PersistentVolumeClaim + are also valid here. + properties: + accessModes: + description: 'accessModes contains the + desired access modes the volume should + have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be + used to specify either: * An existing + VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) + If the provisioner or an external + controller can support the specified + data source, it will create a new + volume based on the contents of the + specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource + contents will be copied to dataSourceRef, + and dataSourceRef contents will be + copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace + is specified, then dataSourceRef will + not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any other + third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of + resource being referenced + type: string + name: + description: Name is the name of + resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies + the object from which to populate + the volume with data, if a non-empty + volume is desired. This may be any + object from a non-empty API group + (non core object) or a PersistentVolumeClaim + object. When this field is specified, + volume binding will only succeed if + the type of the specified object matches + some installed volume populator or + dynamic provisioner. This field will + replace the functionality of the dataSource + field and as such if both fields are + non-empty, they must have the same + value. For backwards compatibility, + when namespace isn''t specified in + dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to + the same value automatically if one + of them is empty and the other is + non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t + set to the same value and must be + empty. There are three important differences + between dataSource and dataSourceRef: + * While dataSource only allows two + specific types of objects, dataSourceRef + allows any non-core object, as well + as PersistentVolumeClaim objects. + * While dataSource ignores disallowed + values (dropping them), dataSourceRef + preserves all values, and generates + an error if a disallowed value is + specified. * While dataSource only + allows local objects, dataSourceRef + allows objects in any namespaces. + (Beta) Using this field requires the + AnyVolumeDataSource feature gate to + be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the + CrossNamespaceVolumeDataSource feature + gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group + for the resource being referenced. + If APIGroup is not specified, + the specified Kind must be in + the core API group. For any other + third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of + resource being referenced + type: string + name: + description: Name is the name of + resource being referenced + type: string + namespace: + description: Namespace is the namespace + of resource being referenced Note + that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent + namespace to allow that namespace's + owner to accept the reference. + See the ReferenceGrant documentation + for details. (Alpha) This field + requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the + minimum resources the volume should + have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed + to specify resource requirements that + are lower than previous value but + must still be higher than capacity + recorded in the status field of the + claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names + of resources, defined in spec.resourceClaims, + that are used by this container. + \n This is an alpha field and + requires enabling the DynamicResourceAllocation + feature gate. \n This field is + immutable." + items: + description: ResourceClaim references + one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match + the name of one entry in + pod.spec.resourceClaims + of the Pod where this field + is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the + maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes + the minimum amount of compute + resources required. If Requests + is omitted for a container, it + defaults to Limits if that is + explicitly specified, otherwise + to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query + over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is + a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector + requirement is a selector that + contains values, a key, and + an operator that relates the + key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to + a set of values. Valid operators + are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an + array of string values. + If the operator is In or + NotIn, the values array + must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be + empty. This array is replaced + during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map + of {key,value} pairs. A single + {key,value} in the matchLabels + map is equivalent to an element + of matchExpressions, whose key + field is "key", the operator is + "In", and the values array contains + only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: 'storageClassName is the + name of the StorageClass required + by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what + type of volume is required by the + claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding + reference to the PersistentVolume + backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource + that is attached to a kubelet's host machine and + then exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type + to mount. Must be a filesystem type supported + by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. TODO: how do we prevent errors + in the filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun + number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults + to false (read/write). ReadOnly here will + force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target + worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world + wide identifiers (wwids) Either wwids or combination + of targetWWNs and lun must be set, but not + both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume + resource that is provisioned/attached using an + exec based plugin. + properties: + driver: + description: driver is the name of the driver + to use for this volume. + type: string + fsType: + description: fsType is the filesystem type to + mount. Must be a filesystem type supported + by the host operating system. Ex. "ext4", + "xfs", "ntfs". The default filesystem depends + on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field + holds extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults + to false (read/write). ReadOnly here will + force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef + is reference to the secret object containing + sensitive information to pass to the plugin + scripts. This may be empty if no secret object + is specified. If the secret object contains + more than one secret, all secrets are passed + to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume + attached to a kubelet's host machine. This depends + on the Flocker control service being running + properties: + datasetName: + description: datasetName is Name of the dataset + stored as metadata -> name on the dataset + for Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the + dataset. This is unique identifier of a Flocker + dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE + Disk resource that is attached to a kubelet''s + host machine and then exposed to the pod. More + info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the + volume that you want to mount. Tip: Ensure + that the filesystem type is supported by the + host operating system. Examples: "ext4", "xfs", + "ntfs". Implicitly inferred to be "ext4" if + unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + partition: + description: 'partition is the partition in + the volume that you want to mount. If omitted, + the default is to mount by volume name. Examples: + For volume /dev/sda1, you specify the partition + as "1". Similarly, the volume partition for + /dev/sda is "0" (or you can leave the property + empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD + resource in GCE. Used to identify the disk + in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository + at a particular revision. DEPRECATED: GitRepo + is deprecated. To provision a container with a + git repo, mount an EmptyDir into an InitContainer + that clones the repo using git, then mount the + EmptyDir into the Pod''s container.' + properties: + directory: + description: directory is the target directory + name. Must not contain or start with '..'. If + '.' is supplied, the volume directory will + be the git repository. Otherwise, if specified, + the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for + the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount + on the host that shares a pod''s lifetime. More + info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name + that details Glusterfs topology. More info: + https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. + More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs + volume to be mounted with read-only permissions. + Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing + file or directory on the host machine that is + directly exposed to the container. This is generally + used for system agents or other privileged things + that are allowed to see the host machine. Most + containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can + use host directory mounts and who can/can not + mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. + If the path is a symlink, it will follow the + link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults + to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource + that is attached to a kubelet''s host machine + and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether + support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether + support iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type + of the volume that you want to mount. Tip: + Ensure that the filesystem type is supported + by the host operating system. Examples: "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI + Initiator Name. If initiatorName is specified + with iscsiInterface simultaneously, new iSCSI + interface : will + be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified + Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface + Name that uses an iSCSI transport. Defaults + to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun + number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal + List. The portal is either an IP or ip_addr:port + if the port is other than default (typically + TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for + iSCSI target and initiator authentication + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: targetPortal is iSCSI Target Portal. + The Portal is either an IP or ip_addr:port + if the port is other than default (typically + TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL + and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the + host that shares a pod''s lifetime More info: + https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS + server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS + export to be mounted with read-only permissions. + Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address + of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource + represents a reference to a PersistentVolumeClaim + in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this + volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly + setting in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets + host machine + properties: + fsType: + description: fsType is the filesystem type to + mount. Must be a filesystem type supported + by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + pdID: + description: pdID is the ID that identifies + Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx + volume attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem + type to mount Must be a filesystem type supported + by the host operating system. Ex. "ext4", + "xfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a + Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources + secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used + to set permissions on created files by default. + Must be an octal value between 0000 and 0777 + or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON + requires decimal values for mode bits. Directories + within the path are not affected by this setting. + This might be in conflict with other options + that affect the file mode, like fsGroup, and + the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected + along with other supported volume types + properties: + configMap: + description: configMap information about + the configMap data to project + properties: + items: + description: items if unspecified, + each key-value pair in the Data + field of the referenced ConfigMap + will be projected into the volume + as a file whose name is the key + and content is the value. If specified, + the listed keys will be projected + into the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the ConfigMap, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key + to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 + or a decimal value between + 0 and 511. YAML accepts both + octal and decimal values, + JSON requires decimal values + for mode bits. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the + key to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional specify whether + the ConfigMap or its keys must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about + the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile + represents information to create + the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects + a field of the pod: only annotations, + labels, name and namespace + are supported.' + properties: + apiVersion: + description: Version of + the schema the FieldPath + is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the + field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode + bits used to set permissions + on this file, must be an octal + value between 0000 and 0777 + or a decimal value between + 0 and 511. YAML accepts both + octal and decimal values, + JSON requires decimal values + for mode bits. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path + is the relative path name + of the file to be created. + Must not be absolute or contain + the ''..'' path. Must be utf-8 + encoded. The first item of + the relative path must not + start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource + of the container: only resources + limits and requests (limits.cpu, + limits.memory, requests.cpu + and requests.memory) are currently + supported.' + properties: + containerName: + description: 'Container + name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the + output format of the exposed + resources, defaults to + "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: + resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about + the secret data to project + properties: + items: + description: items if unspecified, + each key-value pair in the Data + field of the referenced Secret will + be projected into the volume as + a file whose name is the key and + content is the value. If specified, + the listed keys will be projected + into the specified paths, and unlisted + keys will not be present. If a key + is specified which is not present + in the Secret, the volume setup + will error unless it is marked optional. + Paths must be relative and may not + contain the '..' path or start with + '..'. + items: + description: Maps a string key to + a path within a volume. + properties: + key: + description: key is the key + to project. + type: string + mode: + description: 'mode is Optional: + mode bits used to set permissions + on this file. Must be an octal + value between 0000 and 0777 + or a decimal value between + 0 and 511. YAML accepts both + octal and decimal values, + JSON requires decimal values + for mode bits. If not specified, + the volume defaultMode will + be used. This might be in + conflict with other options + that affect the file mode, + like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative + path of the file to map the + key to. May not be an absolute + path. May not contain the + path element '..'. May not + start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: optional field specify + whether the Secret or its key must + be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information + about the serviceAccountToken data to + project + properties: + audience: + description: audience is the intended + audience of the token. A recipient + of a token must identify itself + with an identifier specified in + the audience of the token, and otherwise + should reject the token. The audience + defaults to the identifier of the + apiserver. + type: string + expirationSeconds: + description: expirationSeconds is + the requested duration of validity + of the service account token. As + the token approaches expiration, + the kubelet volume plugin will proactively + rotate the service account token. + The kubelet will start trying to + rotate the token if the token is + older than 80 percent of its time + to live or if the token is older + than 24 hours.Defaults to 1 hour + and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative + to the mount point of the file to + project the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount + on the host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default + is no group + type: string + readOnly: + description: readOnly here will force the Quobyte + volume to be mounted with read-only permissions. + Defaults to false. + type: boolean + registry: + description: registry represents a single or + multiple Quobyte Registry services specified + as a string as host:port pair (multiple entries + are separated with commas) which acts as the + central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte + volume in the Backend Used with dynamically + provisioned Quobyte volumes, value is set + by the plugin + type: string + user: + description: user to map volume access to Defaults + to serivceaccount user + type: string + volume: + description: volume is a string that references + an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device + mount on the host that shares a pod''s lifetime. + More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type + of the volume that you want to mount. Tip: + Ensure that the filesystem type is supported + by the host operating system. Examples: "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem + from compromising the machine' + type: string + image: + description: 'image is the rados image name. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring + for RBDUser. Default is /etc/ceph/keyring. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph + monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default + is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly + setting in VolumeMounts. Defaults to false. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication + secret for RBDUser. If provided overrides + keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is the rados user name. Default + is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent + volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to + mount. Must be a filesystem type supported + by the host operating system. Ex. "ext4", + "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of + the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of + the ScaleIO Protection Domain for the configured + storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret + for ScaleIO user and other sensitive information. + If this is not provided, Login operation will + fail. + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable + SSL communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the + storage for a volume should be ThickProvisioned + or ThinProvisioned. Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage + Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage + system as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume + already created in the ScaleIO system that + is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should + populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode + bits used to set permissions on created files + by default. Must be an octal value between + 0000 and 0777 or a decimal value between 0 + and 511. YAML accepts both octal and decimal + values, JSON requires decimal values for mode + bits. Defaults to 0644. Directories within + the path are not affected by this setting. + This might be in conflict with other options + that affect the file mode, like fsGroup, and + the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified + which is not present in the Secret, the volume + setup will error unless it is marked optional. + Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 + and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and + decimal values, JSON requires decimal + values for mode bits. If not specified, + the volume defaultMode will be used. + This might be in conflict with other + options that affect the file mode, like + fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path + of the file to map the key to. May not + be an absolute path. May not contain + the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether + the Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the + secret in the pod''s namespace to use. More + info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to + mount. Must be a filesystem type supported + by the host operating system. Ex. "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). + ReadOnly here will force the ReadOnly setting + in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret + to use for obtaining the StorageOS API credentials. If + not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More + info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: volumeName is the human-readable + name of the StorageOS volume. Volume names + are only unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope + of the volume within StorageOS. If no namespace + is specified then the Pod's namespace will + be used. This allows the Kubernetes name + scoping to be mirrored within StorageOS for + tighter integration. Set VolumeName to any + name to override the default behaviour. Set + to "default" if you are not using namespaces + within StorageOS. Namespaces that do not pre-exist + within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere + volume attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. + Must be a filesystem type supported by the + host operating system. Ex. "ext4", "xfs", + "ntfs". Implicitly inferred to be "ext4" if + unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage + Policy Based Management (SPBM) profile ID + associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage + Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies + vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + type: object + securityContext: + description: PodSecurityContext Pod Security Context + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. This field is alpha-level + and will only be honored by components that enable the WindowsHostProcessContainers + feature flag. Setting this field without the feature flag + will result in errors when validating the Pod. All of a + Pod's containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess containers + and non-HostProcess containers). In addition, if HostProcess + is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + size: + description: Size of runtime + type: integer + required: + - allowRestart + - replicaPerGroup + - runtimePodTemplate + - size + type: object + status: + description: RuntimeStatus defines the observed state of Runtime + properties: + nodes: + items: + type: string + type: array + size: + type: integer + required: + - nodes + - size + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/eventmesh-operator/config/crd/kustomization.yaml b/eventmesh-operator/config/crd/kustomization.yaml new file mode 100644 index 0000000000..727b138bb5 --- /dev/null +++ b/eventmesh-operator/config/crd/kustomization.yaml @@ -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. +# + +# This kustomization.yaml is not intended to be run by itself, +# since it depends on service name and namespace that are out of this kustomize package. +# It should be run by config/default +resources: +- bases/eventmesh-operator.eventmesh_runtimes.yaml +- bases/eventmesh-operator.eventmesh_connectors.yaml +#+kubebuilder:scaffold:crdkustomizeresource + +patchesStrategicMerge: +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. +# patches here are for enabling the conversion webhook for each CRD +#- patches/webhook_in_eventmeshoperators.yaml +#+kubebuilder:scaffold:crdkustomizewebhookpatch + +# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. +# patches here are for enabling the CA injection for each CRD +#- patches/cainjection_in_eventmeshoperators.yaml +#+kubebuilder:scaffold:crdkustomizecainjectionpatch + +# the following config is for teaching kustomize how to do kustomization for CRDs. +configurations: +- kustomizeconfig.yaml diff --git a/eventmesh-operator/config/crd/kustomizeconfig.yaml b/eventmesh-operator/config/crd/kustomizeconfig.yaml new file mode 100644 index 0000000000..85c3fa88a0 --- /dev/null +++ b/eventmesh-operator/config/crd/kustomizeconfig.yaml @@ -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. +# + +# This file is for teaching kustomize how to substitute name and namespace reference in CRD +nameReference: +- kind: Service + version: v1 + fieldSpecs: + - kind: CustomResourceDefinition + version: v1 + group: apiextensions.k8s.io + path: spec/conversion/webhook/clientConfig/service/name + +namespace: +- kind: CustomResourceDefinition + version: v1 + group: apiextensions.k8s.io + path: spec/conversion/webhook/clientConfig/service/namespace + create: false + +varReference: +- path: metadata/annotations diff --git a/eventmesh-operator/config/crd/patches/cainjection_in_eventmeshoperators.yaml b/eventmesh-operator/config/crd/patches/cainjection_in_eventmeshoperators.yaml new file mode 100644 index 0000000000..4e262406a0 --- /dev/null +++ b/eventmesh-operator/config/crd/patches/cainjection_in_eventmeshoperators.yaml @@ -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. +# + +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: eventmeshoperators.eventmesh-operator.eventmesh diff --git a/eventmesh-operator/config/crd/patches/webhook_in_eventmeshoperators.yaml b/eventmesh-operator/config/crd/patches/webhook_in_eventmeshoperators.yaml new file mode 100644 index 0000000000..ced7cacb2d --- /dev/null +++ b/eventmesh-operator/config/crd/patches/webhook_in_eventmeshoperators.yaml @@ -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. +# + +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: eventmeshoperators.eventmesh-operator.eventmesh +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/eventmesh-operator/config/default/kustomization.yaml b/eventmesh-operator/config/default/kustomization.yaml new file mode 100644 index 0000000000..d4c395e546 --- /dev/null +++ b/eventmesh-operator/config/default/kustomization.yaml @@ -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. +# + +# Adds namespace to all resources. +namespace: eventmesh-operator-system + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: eventmesh-operator- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../crd +- ../rbac +- ../manager +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +#- ../webhook +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. +#- ../certmanager +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +#- ../prometheus + +patchesStrategicMerge: +# Protect the /metrics endpoint by putting it behind auth. +# If you want your controller-manager to expose the /metrics +# endpoint w/o any authn/z, please comment the following line. +- manager_auth_proxy_patch.yaml + + + +# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in +# crd/kustomization.yaml +#- manager_webhook_patch.yaml + +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. +# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. +# 'CERTMANAGER' needs to be enabled to use ca injection +#- webhookcainjection_patch.yaml + +# the following config is for teaching kustomize how to do var substitution +vars: +# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. +#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +# fieldref: +# fieldpath: metadata.namespace +#- name: CERTIFICATE_NAME +# objref: +# kind: Certificate +# group: cert-manager.io +# version: v1 +# name: serving-cert # this name should match the one in certificate.yaml +#- name: SERVICE_NAMESPACE # namespace of the service +# objref: +# kind: Service +# version: v1 +# name: webhook-service +# fieldref: +# fieldpath: metadata.namespace +#- name: SERVICE_NAME +# objref: +# kind: Service +# version: v1 +# name: webhook-service diff --git a/eventmesh-operator/config/default/manager_auth_proxy_patch.yaml b/eventmesh-operator/config/default/manager_auth_proxy_patch.yaml new file mode 100644 index 0000000000..e74132a855 --- /dev/null +++ b/eventmesh-operator/config/default/manager_auth_proxy_patch.yaml @@ -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. +# + +# This patch inject a sidecar container which is a HTTP proxy for the +# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - arm64 + - ppc64le + - s390x + - key: kubernetes.io/os + operator: In + values: + - linux + containers: + - name: kube-rbac-proxy + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1 + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=0" + ports: + - containerPort: 8443 + protocol: TCP + name: https + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + - name: manager + args: + - "--health-probe-bind-address=:8081" + - "--metrics-bind-address=127.0.0.1:8080" + - "--leader-elect" diff --git a/eventmesh-operator/config/default/manager_config_patch.yaml b/eventmesh-operator/config/default/manager_config_patch.yaml new file mode 100644 index 0000000000..483d5c6a2e --- /dev/null +++ b/eventmesh-operator/config/default/manager_config_patch.yaml @@ -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. +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager diff --git a/eventmesh-operator/config/manager/kustomization.yaml b/eventmesh-operator/config/manager/kustomization.yaml new file mode 100644 index 0000000000..8cc58d49df --- /dev/null +++ b/eventmesh-operator/config/manager/kustomization.yaml @@ -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. +# + +resources: +- manager.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: controller + newTag: latest diff --git a/eventmesh-operator/config/manager/manager.yaml b/eventmesh-operator/config/manager/manager.yaml new file mode 100644 index 0000000000..a5e1a12233 --- /dev/null +++ b/eventmesh-operator/config/manager/manager.yaml @@ -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. +# + +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + app.kubernetes.io/name: namespace + app.kubernetes.io/instance: system + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager + app.kubernetes.io/name: deployment + app.kubernetes.io/instance: controller-manager + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + # TODO(user): Uncomment the following code to configure the nodeAffinity expression + # according to the platforms which are supported by your solution. + # It is considered best practice to support multiple architectures. You can + # build your manager image using the makefile target docker-buildx. + # affinity: + # nodeAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # nodeSelectorTerms: + # - matchExpressions: + # - key: kubernetes.io/arch + # operator: In + # values: + # - amd64 + # - arm64 + # - ppc64le + # - s390x + # - key: kubernetes.io/os + # operator: In + # values: + # - linux + securityContext: + runAsNonRoot: true + # TODO(user): For common cases that do not require escalating privileges + # it is recommended to ensure that all your Pods/Containers are restrictive. + # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted + # Please uncomment the following code if your project does NOT have to work on old Kubernetes + # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ). + # seccompProfile: + # type: RuntimeDefault + containers: + - command: + - /manager + args: + - --leader-elect + image: controller:latest + name: manager + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + # TODO(user): Configure the resources accordingly based on the project requirements. + # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + serviceAccountName: controller-manager + terminationGracePeriodSeconds: 10 diff --git a/eventmesh-operator/config/manifests/kustomization.yaml b/eventmesh-operator/config/manifests/kustomization.yaml new file mode 100644 index 0000000000..ffcc68cbc6 --- /dev/null +++ b/eventmesh-operator/config/manifests/kustomization.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. +# + +# These resources constitute the fully configured set of manifests +# used to generate the 'manifests/' directory in a bundle. +resources: +- bases/eventmesh-operator.clusterserviceversion.yaml +- ../default +- ../samples +- ../scorecard + +# [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. +# Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. +# These patches remove the unnecessary "cert" volume and its manager container volumeMount. +#patchesJson6902: +#- target: +# group: apps +# version: v1 +# kind: Deployment +# name: controller-manager +# namespace: system +# patch: |- +# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. +# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. +# - op: remove +# path: /spec/template/spec/containers/1/volumeMounts/0 +# # Remove the "cert" volume, since OLM will create and mount a set of certs. +# # Update the indices in this path if adding or removing volumes in the manager's Deployment. +# - op: remove +# path: /spec/template/spec/volumes/0 diff --git a/eventmesh-operator/config/prometheus/kustomization.yaml b/eventmesh-operator/config/prometheus/kustomization.yaml new file mode 100644 index 0000000000..8995548d73 --- /dev/null +++ b/eventmesh-operator/config/prometheus/kustomization.yaml @@ -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. +# + +resources: +- monitor.yaml diff --git a/eventmesh-operator/config/prometheus/monitor.yaml b/eventmesh-operator/config/prometheus/monitor.yaml new file mode 100644 index 0000000000..72ecd1f6a6 --- /dev/null +++ b/eventmesh-operator/config/prometheus/monitor.yaml @@ -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. +# + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + app.kubernetes.io/name: servicemonitor + app.kubernetes.io/instance: controller-manager-metrics-monitor + app.kubernetes.io/component: metrics + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - path: /metrics + port: https + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + tlsConfig: + insecureSkipVerify: true + selector: + matchLabels: + control-plane: controller-manager diff --git a/eventmesh-operator/config/rbac/auth_proxy_client_clusterrole.yaml b/eventmesh-operator/config/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 0000000000..7b9528c3c1 --- /dev/null +++ b/eventmesh-operator/config/rbac/auth_proxy_client_clusterrole.yaml @@ -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. +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: metrics-reader + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/eventmesh-operator/config/rbac/auth_proxy_role.yaml b/eventmesh-operator/config/rbac/auth_proxy_role.yaml new file mode 100644 index 0000000000..60fcc84420 --- /dev/null +++ b/eventmesh-operator/config/rbac/auth_proxy_role.yaml @@ -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. +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: proxy-role + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/eventmesh-operator/config/rbac/auth_proxy_role_binding.yaml b/eventmesh-operator/config/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 0000000000..fb8506e637 --- /dev/null +++ b/eventmesh-operator/config/rbac/auth_proxy_role_binding.yaml @@ -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. +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: clusterrolebinding + app.kubernetes.io/instance: proxy-rolebinding + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: proxy-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/eventmesh-operator/config/rbac/auth_proxy_service.yaml b/eventmesh-operator/config/rbac/auth_proxy_service.yaml new file mode 100644 index 0000000000..20dd3d9efb --- /dev/null +++ b/eventmesh-operator/config/rbac/auth_proxy_service.yaml @@ -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. +# + +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + app.kubernetes.io/name: service + app.kubernetes.io/instance: controller-manager-metrics-service + app.kubernetes.io/component: kube-rbac-proxy + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + control-plane: controller-manager diff --git a/eventmesh-operator/config/rbac/eventmeshoperator_editor_role.yaml b/eventmesh-operator/config/rbac/eventmeshoperator_editor_role.yaml new file mode 100644 index 0000000000..eeeee009c4 --- /dev/null +++ b/eventmesh-operator/config/rbac/eventmeshoperator_editor_role.yaml @@ -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. +# + +# permissions for end users to edit eventmeshoperators. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: eventmeshoperator-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: eventmeshoperator-editor-role +rules: +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - eventmeshoperators + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - eventmeshoperators/status + verbs: + - get diff --git a/eventmesh-operator/config/rbac/eventmeshoperator_viewer_role.yaml b/eventmesh-operator/config/rbac/eventmeshoperator_viewer_role.yaml new file mode 100644 index 0000000000..dce25a53e0 --- /dev/null +++ b/eventmesh-operator/config/rbac/eventmeshoperator_viewer_role.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. +# + +# permissions for end users to view eventmeshoperators. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: eventmeshoperator-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: eventmeshoperator-viewer-role +rules: +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - eventmeshoperators + verbs: + - get + - list + - watch +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - eventmeshoperators/status + verbs: + - get diff --git a/eventmesh-operator/config/rbac/kustomization.yaml b/eventmesh-operator/config/rbac/kustomization.yaml new file mode 100644 index 0000000000..b6005d5f2b --- /dev/null +++ b/eventmesh-operator/config/rbac/kustomization.yaml @@ -0,0 +1,35 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +resources: +# All RBAC will be applied under this service account in +# the deployment namespace. You may comment out this resource +# if your manager will use a service account that exists at +# runtime. Be sure to update RoleBinding and ClusterRoleBinding +# subjects if changing service account names. +- service_account.yaml +- role.yaml +- role_binding.yaml +- leader_election_role.yaml +- leader_election_role_binding.yaml +# Comment the following 4 lines if you want to disable +# the auth proxy (https://github.com/brancz/kube-rbac-proxy) +# which protects your /metrics endpoint. +- auth_proxy_service.yaml +- auth_proxy_role.yaml +- auth_proxy_role_binding.yaml +- auth_proxy_client_clusterrole.yaml diff --git a/eventmesh-operator/config/rbac/leader_election_role.yaml b/eventmesh-operator/config/rbac/leader_election_role.yaml new file mode 100644 index 0000000000..3ebce84cb1 --- /dev/null +++ b/eventmesh-operator/config/rbac/leader_election_role.yaml @@ -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. +# + +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/name: role + app.kubernetes.io/instance: leader-election-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: leader-election-role +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/eventmesh-operator/config/rbac/leader_election_role_binding.yaml b/eventmesh-operator/config/rbac/leader_election_role_binding.yaml new file mode 100644 index 0000000000..5ae79ac276 --- /dev/null +++ b/eventmesh-operator/config/rbac/leader_election_role_binding.yaml @@ -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. +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: rolebinding + app.kubernetes.io/instance: leader-election-rolebinding + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: eventmesh-operator + app.kubernetes.io/part-of: eventmesh-operator + app.kubernetes.io/managed-by: kustomize + name: leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/eventmesh-operator/config/rbac/role.yaml b/eventmesh-operator/config/rbac/role.yaml new file mode 100644 index 0000000000..2391c5a67f --- /dev/null +++ b/eventmesh-operator/config/rbac/role.yaml @@ -0,0 +1,150 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: eventmesh-operator +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - pods + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - connectors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - connectors/finalizers + verbs: + - update +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - connectors/status + verbs: + - get + - patch + - update +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - runtimes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - runtimes/finalizers + verbs: + - update +- apiGroups: + - eventmesh-operator.eventmesh + resources: + - runtimes/status + verbs: + - get + - patch + - update diff --git a/eventmesh-operator/config/rbac/role_binding.yaml b/eventmesh-operator/config/rbac/role_binding.yaml new file mode 100644 index 0000000000..7c1c095234 --- /dev/null +++ b/eventmesh-operator/config/rbac/role_binding.yaml @@ -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. +# + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: eventmesh-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: eventmesh-operator +subjects: +- kind: ServiceAccount + name: eventmesh-operator + namespace: default diff --git a/eventmesh-operator/config/rbac/service_account.yaml b/eventmesh-operator/config/rbac/service_account.yaml new file mode 100644 index 0000000000..7279388adc --- /dev/null +++ b/eventmesh-operator/config/rbac/service_account.yaml @@ -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. +# + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: eventmesh-operator + namespace: default diff --git a/eventmesh-operator/config/samples/eventmesh_operator.yaml b/eventmesh-operator/config/samples/eventmesh_operator.yaml new file mode 100644 index 0000000000..29164e9049 --- /dev/null +++ b/eventmesh-operator/config/samples/eventmesh_operator.yaml @@ -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. +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: eventmesh-operator +spec: + replicas: 1 + selector: + matchLabels: + name: eventmesh-operator + template: + metadata: + labels: + name: eventmesh-operator + spec: + serviceAccountName: eventmesh-operator + terminationGracePeriodSeconds: 10 + containers: + - name: eventmesh-operator + # image + image: alonexc/eventmesh-operator:latest + command: + - /manager + args: + - --leader-elect + imagePullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 200m + memory: 2048Mi + requests: + cpu: 100m + memory: 1024Mi + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "eventmesh-operator" diff --git a/eventmesh-operator/config/samples/eventmesh_v1_connectors_rocketmq.yaml b/eventmesh-operator/config/samples/eventmesh_v1_connectors_rocketmq.yaml new file mode 100644 index 0000000000..96cff08456 --- /dev/null +++ b/eventmesh-operator/config/samples/eventmesh_v1_connectors_rocketmq.yaml @@ -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. +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: connector-rocketmq-config +data: + server-config.yml: | + sourceEnable: true + sinkEnable: true + sink-config.yml: | + pubSubConfig: + meshAddress: runtime-cluster-service:10000 + subject: TopicTest + idc: FT + env: PRD + group: rocketmqSink + appId: 5031 + userName: rocketmqSinkUser + passWord: rocketmqPassWord + connectorConfig: + connectorName: rocketmqSink + nameServer: 127.0.0.1:9876 + topic: TopicTest + source-config.yml: | + pubSubConfig: + meshAddress: runtime-cluster-service:10000 + subject: TopicTest + idc: FT + env: PRD + group: rocketmqSource + appId: 5032 + userName: rocketmqSourceUser + passWord: rocketmqPassWord + connectorConfig: + connectorName: rocketmqSource + nameserver: 127.0.0.1:9876 + topic: TopicTest + commitOffsetIntervalMs: 5000 + offsetStorageConfig: + offsetStorageType: nacos + offsetStorageAddr: 127.0.0.1:8848 + extensions: { + #same with topic + dataId: TopicTest, + #same with group + group: rocketmqSource + } +--- + +apiVersion: eventmesh-operator.eventmesh/v1 +kind: Connectors +metadata: + name: connector-rocketmq +spec: + # size of connector-rocketmq + size: 1 + # imagePullPolicy is the image pull policy + imagePullPolicy: Always + # set DNS policy for the pod + # dnsPolicy: ClusterFirstWithHostNet + # define the connector-rocketmq container. + connectorContainers: + - name: connector-rocketmq + # connectorImage is the customized docker image repo of the EventMesh Connectors + image: alonexc/eventmesh-connectors:connector-rocketmq-1.9.0 + # mount the configuration file to the container. + volumeMounts: + - mountPath: "/data/app/eventmesh-connector-rocketmq/conf" + name: connector-rocketmq-config + # resources describes the compute resource requirements and limits + resources: + requests: + memory: 512Mi + cpu: 250m + limits: + memory: 1024Mi + cpu: 1000m + # configuration file settings to be mounted. + volumes: + - name: connector-rocketmq-config + configMap: + name: connector-rocketmq-config + items: + - key: server-config.yml + path: server-config.yml + - key: sink-config.yml + path: sink-config.yml + - key: source-config.yml + path: source-config.yml \ No newline at end of file diff --git a/eventmesh-operator/config/samples/eventmesh_v1_runtime.yaml b/eventmesh-operator/config/samples/eventmesh_v1_runtime.yaml new file mode 100644 index 0000000000..ee94d606fb --- /dev/null +++ b/eventmesh-operator/config/samples/eventmesh_v1_runtime.yaml @@ -0,0 +1,308 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +apiVersion: v1 +kind: ConfigMap +metadata: + name: runtime-config +data: + rocketmq.properties: | + #######################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=******** + + eventmesh.properties: | + ###############################EVNETMESH-runtime ENV################################# + eventMesh.server.idc=DEFAULT + eventMesh.server.env=PRD + eventMesh.server.provide.protocols=HTTP,TCP,GRPC + 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 + #metaStorage + eventMesh.server.metaStorage.metaStorageIntervalInMills=10000 + eventMesh.server.metaStorage.fetchMetaStorageAddrIntervalInMills=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 + + #storage plugin + eventMesh.storage.plugin.type=standalone + + #security plugin + eventMesh.server.security.enabled=false + eventMesh.security.plugin.type=security + eventMesh.security.validation.type.token=false + eventMesh.security.publickey= + + #metaStorage plugin + eventMesh.metaStorage.plugin.enabled=false + eventMesh.metaStorage.plugin.type=nacos + eventMesh.metaStorage.plugin.server-addr=127.0.0.1:8848 + eventMesh.metaStorage.plugin.username=nacos + eventMesh.metaStorage.plugin.password=nacos + # metaStorage plugin: nacos + #eventMesh.metaStorage.nacos.endpoint= + #eventMesh.metaStorage.nacos.accessKey= + #eventMesh.metaStorage.nacos.secretKey= + #eventMesh.metaStorage.nacos.clusterName= + #eventMesh.metaStorage.nacos.namespace= + # The default value is half of CPU's num + #eventMesh.metaStorage.nacos.namingPollingThreadCount=5 + + # metaStorage plugin: zookeeper + #eventMesh.metaStorage.zookeeper.scheme= + #eventMesh.metaStorage.zookeeper.auth= + #eventMesh.metaStorage.zookeeper.connectionTimeoutMs= + #eventMesh.metaStorage.zookeeper.sessionTimeoutMs= + + # Fully qualified name of org.apache.curator.RetryPolicy implementation + #eventMesh.metaStorage.zookeeper.retryPolicy.class= + + # Constructor arguments for different org.apache.curator.RetryPolicy implementations + #eventMesh.metaStorage.zookeeper.retryPolicy.baseSleepTimeMs= + #eventMesh.metaStorage.zookeeper.retryPolicy.maxRetries= + #eventMesh.metaStorage.zookeeper.retryPolicy.maxSleepTimeMs= + #eventMesh.metaStorage.zookeeper.retryPolicy.retryIntervalMs= + #eventMesh.metaStorage.zookeeper.retryPolicy.nTimes= + #eventMesh.metaStorage.zookeeper.retryPolicy.sleepMsBetweenRetries= + + # The TLS configuration of metaStorage plugin: consul + # keyStoreInstanceType's value can refer to com.ecwid.consul.transport.TLSConfig.KeyStoreInstanceType + #eventMesh.metaStorage.consul.tls.keyStoreInstanceType= + #eventMesh.metaStorage.consul.tls.certificatePath= + #eventMesh.metaStorage.consul.tls.certificatePassword= + #eventMesh.metaStorage.consul.tls.keyStorePath= + #eventMesh.metaStorage.consul.tls.keyStorePassword= + + # 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 CloudEvent sending mode. This property is the same as the eventMesh.storage.plugin.type configuration. + eventMesh.webHook.producer.storage=standalone + server.env: | + APP_START_JVM_OPTION:::-server -Xms128M -Xmx256M -Xmn128m -XX:SurvivorRatio=4 -Duser.language=zh + log4j2.xml: | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +--- + +apiVersion: eventmesh-operator.eventmesh/v1 +kind: Runtime +metadata: + name: eventmesh-runtime +spec: + # size is the number of the runtime cluster + size: 1 + # replicaPerGroup is the number of each runtime cluster + replicaPerGroup: 1 + # allowRestart defines whether allow pod restart + allowRestart: true + # define runtime pod template + runtimePodTemplate: + template: + spec: + # Host networking requested for this pod. Use the host's network namespace. + # If this option is set, the ports that will be used must be specified. + # Default to false. + hostNetwork: false + # Defaults to "ClusterFirst" + # Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. + # DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. + # To have DNS options set along with hostNetwork, you have to specify DNS policy + # explicitly to 'ClusterFirstWithHostNet'. + dnsPolicy: ClusterFirstWithHostNet + # define the runtime container. + containers: + - name: eventmesh-runtime + image: alonexc/eventmesh-runtime:runtime-1.9.0 + ports: + - name: tcp + containerPort: 10000 + - name: http + containerPort: 10105 + - name: grpc + containerPort: 10205 + volumeMounts: + - mountPath: "/data/app/eventmesh/conf" + name: runtime-config + # imagePullPolicy is the image pull policy + imagePullPolicy: Always + # resources describes the compute resource requirements and limits + resources: + requests: + memory: 2048Mi + cpu: 2000m + limits: + memory: 8192Mi + cpu: 8000m + # configuration file settings to be mounted. + volumes: + - name: runtime-config + configMap: + name: runtime-config + items: + - key: rocketmq.properties + path: rocketmq.properties + - key: eventmesh.properties + path: eventmesh.properties + - key: server.env + path: server.env + - key: log4j2.xml + path: log4j2.xml \ No newline at end of file diff --git a/eventmesh-operator/config/samples/eventmesh_v1_runtime_cluster.yaml b/eventmesh-operator/config/samples/eventmesh_v1_runtime_cluster.yaml new file mode 100644 index 0000000000..ec9d0f7274 --- /dev/null +++ b/eventmesh-operator/config/samples/eventmesh_v1_runtime_cluster.yaml @@ -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. +# + +apiVersion: v1 +kind: Service +metadata: + name: runtime-cluster-service +spec: + type: ClusterIP + selector: + app: eventmesh-runtime + ports: + - name: tcp + port: 10000 + targetPort: 10000 + protocol: TCP +--- \ No newline at end of file diff --git a/eventmesh-operator/config/samples/kustomization.yaml b/eventmesh-operator/config/samples/kustomization.yaml new file mode 100644 index 0000000000..ab43080bab --- /dev/null +++ b/eventmesh-operator/config/samples/kustomization.yaml @@ -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. +# + +## Append samples you want in your CSV to this file as resources ## +resources: +- eventmesh_v1_runtime.yaml +- eventmesh_v1_connectors_rocketmq.yaml +#+kubebuilder:scaffold:manifestskustomizesamples diff --git a/eventmesh-operator/config/scorecard/bases/config.yaml b/eventmesh-operator/config/scorecard/bases/config.yaml new file mode 100644 index 0000000000..6d618c1474 --- /dev/null +++ b/eventmesh-operator/config/scorecard/bases/config.yaml @@ -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. +# + +apiVersion: scorecard.operatorframework.io/v1alpha3 +kind: Configuration +metadata: + name: config +stages: +- parallel: true + tests: [] diff --git a/eventmesh-operator/config/scorecard/kustomization.yaml b/eventmesh-operator/config/scorecard/kustomization.yaml new file mode 100644 index 0000000000..606f84d0ed --- /dev/null +++ b/eventmesh-operator/config/scorecard/kustomization.yaml @@ -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. +# + +resources: +- bases/config.yaml +patchesJson6902: +- path: patches/basic.config.yaml + target: + group: scorecard.operatorframework.io + version: v1alpha3 + kind: Configuration + name: config +- path: patches/olm.config.yaml + target: + group: scorecard.operatorframework.io + version: v1alpha3 + kind: Configuration + name: config +#+kubebuilder:scaffold:patchesJson6902 diff --git a/eventmesh-operator/config/scorecard/patches/basic.config.yaml b/eventmesh-operator/config/scorecard/patches/basic.config.yaml new file mode 100644 index 0000000000..e1e6431a98 --- /dev/null +++ b/eventmesh-operator/config/scorecard/patches/basic.config.yaml @@ -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. +# + +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - basic-check-spec + image: quay.io/operator-framework/scorecard-test:v1.31.0 + labels: + suite: basic + test: basic-check-spec-test diff --git a/eventmesh-operator/config/scorecard/patches/olm.config.yaml b/eventmesh-operator/config/scorecard/patches/olm.config.yaml new file mode 100644 index 0000000000..a91313d862 --- /dev/null +++ b/eventmesh-operator/config/scorecard/patches/olm.config.yaml @@ -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. +# + +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-bundle-validation + image: quay.io/operator-framework/scorecard-test:v1.31.0 + labels: + suite: olm + test: olm-bundle-validation-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-crds-have-validation + image: quay.io/operator-framework/scorecard-test:v1.31.0 + labels: + suite: olm + test: olm-crds-have-validation-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-crds-have-resources + image: quay.io/operator-framework/scorecard-test:v1.31.0 + labels: + suite: olm + test: olm-crds-have-resources-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-spec-descriptors + image: quay.io/operator-framework/scorecard-test:v1.31.0 + labels: + suite: olm + test: olm-spec-descriptors-test +- op: add + path: /stages/0/tests/- + value: + entrypoint: + - scorecard-test + - olm-status-descriptors + image: quay.io/operator-framework/scorecard-test:v1.31.0 + labels: + suite: olm + test: olm-status-descriptors-test diff --git a/eventmesh-operator/controllers/eventmesh_connectors/connectors_controller.go b/eventmesh-operator/controllers/eventmesh_connectors/connectors_controller.go new file mode 100644 index 0000000000..dd5850cef3 --- /dev/null +++ b/eventmesh-operator/controllers/eventmesh_connectors/connectors_controller.go @@ -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. + */ + +package eventmesh_connectors + +import ( + "context" + "fmt" + eventmeshoperatorv1 "github.com/apache/eventmesh/eventmesh-operator/api/v1" + "github.com/apache/eventmesh/eventmesh-operator/share" + "github.com/go-logr/logr" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "reflect" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + "strconv" + _ "strings" + "time" +) + +// ConnectorsReconciler reconciles a Connectors object +type ConnectorsReconciler struct { + Client client.Client + Scheme *runtime.Scheme + Logger logr.Logger +} + +// SetupWithManager creates a new Connectors Controller and adds it to the Manager. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func SetupWithManager(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &ConnectorsReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Logger: mgr.GetLogger().WithName("connector"), + } +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("connectors-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to primary resource connector + err = c.Watch(&source.Kind{Type: &eventmeshoperatorv1.Connectors{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // TODO(user): Modify this to be the types you create that are owned by the primary resource + // Watch for changes to secondary resource Pods and requeue the owner runtime + err = c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForOwner{ + IsController: true, + OwnerType: &eventmeshoperatorv1.Connectors{}, + }) + if err != nil { + return err + } + + return nil +} + +//+kubebuilder:rbac:groups=eventmesh-operator.eventmesh,resources=connectors,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=eventmesh-operator.eventmesh,resources=connectors/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=eventmesh-operator.eventmesh,resources=connectors/finalizers,verbs=update +//+kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups="",resources=pods/exec,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups="apps",resources=statefulsets,verbs=get;list;watch;create;update;patch;delete + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the EventMeshOperator object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.14.1/pkg/reconcile +func (r ConnectorsReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { + r.Logger.Info("connectors start reconciling", + "Namespace", req.Namespace, "Namespace", req.Name) + + connector := &eventmeshoperatorv1.Connectors{} + err := r.Client.Get(context.TODO(), req.NamespacedName, connector) + if err != nil { + // If it's a not found exception, it means the cr has been deleted. + if errors.IsNotFound(err) { + r.Logger.Info("connector resource not found. Ignoring since object must be deleted.") + return reconcile.Result{}, err + } + r.Logger.Error(err, "Failed to get connector") + return reconcile.Result{}, err + } + + for { + if share.IsEventMeshRuntimeInitialized { + break + } else { + r.Logger.Info("connector Waiting for runtime ready...") + time.Sleep(time.Duration(share.WaitForRuntimePodNameReadyInSecond) * time.Second) + } + } + + connectorStatefulSet := r.getConnectorStatefulSet(connector) + // Check if the statefulSet already exists, if not create a new one + found := &appsv1.StatefulSet{} + err = r.Client.Get(context.TODO(), types.NamespacedName{ + Name: connectorStatefulSet.Name, + Namespace: connectorStatefulSet.Namespace}, found) + if err != nil && errors.IsNotFound(err) { + r.Logger.Info("Creating a new Connector StatefulSet.", + "StatefulSet.Namespace", connectorStatefulSet.Namespace, + "StatefulSet.Name", connectorStatefulSet.Name) + err = r.Client.Create(context.TODO(), connectorStatefulSet) + if err != nil { + r.Logger.Error(err, "Failed to create new Connector StatefulSet", + "StatefulSet.Namespace", connectorStatefulSet.Namespace, + "StatefulSet.Name", connectorStatefulSet.Name) + } + time.Sleep(time.Duration(3) * time.Second) + } else if err != nil { + r.Logger.Error(err, "Failed to list Connector StatefulSet.") + } + + podList := &corev1.PodList{} + labelSelector := labels.SelectorFromSet(getLabels()) + listOps := &client.ListOptions{ + Namespace: connector.Namespace, + LabelSelector: labelSelector, + } + err = r.Client.List(context.TODO(), podList, listOps) + if err != nil { + r.Logger.Error(err, "Failed to list pods.", "Connector.Namespace", connector.Namespace, + "Connector.Name", connector.Name) + return reconcile.Result{}, err + } + podNames := getConnectorPodNames(podList.Items) + r.Logger.Info(fmt.Sprintf("Status.Nodes = %s", connector.Status.Nodes)) + r.Logger.Info(fmt.Sprintf("podNames = %s", podNames)) + // Ensure every pod is in running phase + for _, pod := range podList.Items { + if !reflect.DeepEqual(pod.Status.Phase, corev1.PodRunning) { + r.Logger.Info("pod " + pod.Name + " phase is " + string(pod.Status.Phase) + ", wait for a moment...") + } + } + + if podNames != nil { + connector.Status.Nodes = podNames + r.Logger.Info(fmt.Sprintf("Connector.Status.Nodes = %s", connector.Status.Nodes)) + // Update status.Size if needed + if connector.Spec.Size != connector.Status.Size { + r.Logger.Info("Connector.Status.Size = " + strconv.Itoa(connector.Status.Size)) + r.Logger.Info("Connector.Spec.Size = " + strconv.Itoa(connector.Spec.Size)) + connector.Status.Size = connector.Spec.Size + err = r.Client.Status().Update(context.TODO(), connector) + if err != nil { + r.Logger.Error(err, "Failed to update Connector Size status.") + } + } + + // Update status.Nodes if needed + if !reflect.DeepEqual(podNames, connector.Status.Nodes) { + err = r.Client.Status().Update(context.TODO(), connector) + if err != nil { + r.Logger.Error(err, "Failed to update Connector Nodes status.") + } + } + } else { + r.Logger.Error(err, "Not found connector Pods name") + } + + r.Logger.Info("Successful reconciliation!") + return reconcile.Result{Requeue: true, RequeueAfter: time.Duration(share.RequeueAfterSecond) * time.Second}, nil +} + +func (r ConnectorsReconciler) getConnectorStatefulSet(connector *eventmeshoperatorv1.Connectors) *appsv1.StatefulSet { + + var replica = int32(connector.Spec.Size) + connectorDep := &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: connector.Name, + Namespace: connector.Namespace, + }, + Spec: appsv1.StatefulSetSpec{ + ServiceName: fmt.Sprintf("%s-service", connector.Name), + Replicas: &replica, + Selector: &metav1.LabelSelector{ + MatchLabels: getLabels(), + }, + UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ + Type: appsv1.RollingUpdateStatefulSetStrategyType, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: getLabels(), + }, + Spec: corev1.PodSpec{ + HostNetwork: connector.Spec.HostNetwork, + DNSPolicy: connector.Spec.DNSPolicy, + ServiceAccountName: connector.Spec.ServiceAccountName, + Affinity: connector.Spec.Affinity, + Tolerations: connector.Spec.Tolerations, + NodeSelector: connector.Spec.NodeSelector, + PriorityClassName: connector.Spec.PriorityClassName, + ImagePullSecrets: connector.Spec.ImagePullSecrets, + Containers: []corev1.Container{{ + Resources: connector.Spec.ConnectorContainers[0].Resources, + Image: connector.Spec.ConnectorContainers[0].Image, + Name: connector.Spec.ConnectorContainers[0].Name, + SecurityContext: getConnectorContainerSecurityContext(connector), + ImagePullPolicy: connector.Spec.ImagePullPolicy, + VolumeMounts: connector.Spec.ConnectorContainers[0].VolumeMounts, + }}, + Volumes: connector.Spec.Volumes, + SecurityContext: getConnectorPodSecurityContext(connector), + }, + }, + }, + } + _ = controllerutil.SetControllerReference(connector, connectorDep, r.Scheme) + + return connectorDep +} + +func getConnectorContainerSecurityContext(connector *eventmeshoperatorv1.Connectors) *corev1.SecurityContext { + var securityContext = corev1.SecurityContext{} + if connector.Spec.ContainerSecurityContext != nil { + securityContext = *connector.Spec.ContainerSecurityContext + } + return &securityContext +} + +func getLabels() map[string]string { + return map[string]string{"app": "eventmesh-connector"} +} + +func getConnectorPodSecurityContext(connector *eventmeshoperatorv1.Connectors) *corev1.PodSecurityContext { + var securityContext = corev1.PodSecurityContext{} + if connector.Spec.PodSecurityContext != nil { + securityContext = *connector.Spec.PodSecurityContext + } + return &securityContext +} + +func getConnectorPodNames(pods []corev1.Pod) []string { + var podNames []string + for _, pod := range pods { + podNames = append(podNames, pod.Name) + } + return podNames +} diff --git a/eventmesh-operator/controllers/eventmesh_runtime/runtime_controller.go b/eventmesh-operator/controllers/eventmesh_runtime/runtime_controller.go new file mode 100644 index 0000000000..7bff28c364 --- /dev/null +++ b/eventmesh-operator/controllers/eventmesh_runtime/runtime_controller.go @@ -0,0 +1,337 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package eventmesh_runtime + +import ( + "context" + "fmt" + eventmeshoperatorv1 "github.com/apache/eventmesh/eventmesh-operator/api/v1" + "github.com/apache/eventmesh/eventmesh-operator/share" + "github.com/go-logr/logr" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + "reflect" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + "strconv" + "time" +) + +// RuntimeReconciler reconciles a Runtime object +type RuntimeReconciler struct { + Client client.Client + Scheme *runtime.Scheme + Logger logr.Logger +} + +// SetupWithManager creates a new Runtime Controller and adds it to the Manager. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +func SetupWithManager(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &RuntimeReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Logger: mgr.GetLogger().WithName("runtime"), + } +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("runtime-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to primary resource runtime + err = c.Watch(&source.Kind{Type: &eventmeshoperatorv1.Runtime{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // TODO(user): Modify this to be the types you create that are owned by the primary resource + // Watch for changes to secondary resource Pods and requeue the owner runtime + err = c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForOwner{ + IsController: true, + OwnerType: &eventmeshoperatorv1.Runtime{}, + }) + if err != nil { + return err + } + + return nil +} + +//+kubebuilder:rbac:groups=eventmesh-operator.eventmesh,resources=runtimes,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=eventmesh-operator.eventmesh,resources=runtimes/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=eventmesh-operator.eventmesh,resources=runtimes/finalizers,verbs=update +//+kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups="apps",resources=statefulsets,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups="apps",resources=deployments,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups="",resources=services,verbs=get;list;watch;create;update;patch;delete + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the EventMeshOperator object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.14.1/pkg/reconcile +func (r *RuntimeReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { + r.Logger.Info("eventMeshRuntime start reconciling", + "Namespace", req.Namespace, "Namespace", req.Name) + + eventMeshRuntime := &eventmeshoperatorv1.Runtime{} + err := r.Client.Get(context.TODO(), req.NamespacedName, eventMeshRuntime) + if err != nil { + // If it's a not found exception, it means the cr has been deleted. + if errors.IsNotFound(err) { + r.Logger.Info("eventMeshRuntime resource not found. Ignoring since object must be deleted.") + return reconcile.Result{}, err + } + r.Logger.Error(err, "Failed to get eventMeshRuntime") + return reconcile.Result{}, err + } + r.Logger.Info("get eventMeshRuntime object", "name", eventMeshRuntime.Name) + + if eventMeshRuntime.Status.Size == 0 { + GroupNum = eventMeshRuntime.Spec.Size + } else { + GroupNum = eventMeshRuntime.Status.Size + } + + replicaPerGroup := eventMeshRuntime.Spec.ReplicaPerGroup + r.Logger.Info("GroupNum=" + strconv.Itoa(GroupNum) + ", replicaPerGroup=" + strconv.Itoa(replicaPerGroup)) + + for groupIndex := 0; groupIndex < GroupNum; groupIndex++ { + r.Logger.Info("Check eventMeshRuntime cluster " + strconv.Itoa(groupIndex+1) + "/" + strconv.Itoa(GroupNum)) + runtimeDep := r.getEventMeshRuntimeStatefulSet(eventMeshRuntime, groupIndex, 0) + + // Check if the statefulSet already exists, if not create a new one + found := &appsv1.StatefulSet{} + err = r.Client.Get(context.TODO(), types.NamespacedName{ + Name: runtimeDep.Name, + Namespace: runtimeDep.Namespace, + }, found) + if err != nil && errors.IsNotFound(err) { + r.Logger.Info("Creating a new eventMeshRuntime StatefulSet.", + "StatefulSet.Namespace", runtimeDep.Namespace, + "StatefulSet.Name", runtimeDep.Name) + err = r.Client.Create(context.TODO(), runtimeDep) + if err != nil { + r.Logger.Error(err, "Failed to create new StatefulSet", + "StatefulSet.Namespace", runtimeDep.Namespace, + "StatefulSet.Name", runtimeDep.Name) + } + time.Sleep(time.Duration(3) * time.Second) + } else if err != nil { + r.Logger.Error(err, "Failed to get eventMeshRuntime StatefulSet.") + } + } + if eventMeshRuntime.Spec.AllowRestart { + for groupIndex := 0; groupIndex < eventMeshRuntime.Spec.Size; groupIndex++ { + runtimeName := eventMeshRuntime.Name + "-" + strconv.Itoa(groupIndex) + r.Logger.Info("update eventMeshRuntime", "runtimeName", runtimeName) + // update + deployment := r.getEventMeshRuntimeStatefulSet(eventMeshRuntime, groupIndex, 0) + found := &appsv1.StatefulSet{} + err = r.Client.Get(context.TODO(), types.NamespacedName{ + Name: deployment.Name, + Namespace: deployment.Namespace, + }, found) + if err != nil { + r.Logger.Error(err, "Failed to get eventMeshRuntime StatefulSet.") + } else { + err = r.Client.Update(context.TODO(), found) + if err != nil { + r.Logger.Error(err, "Failed to update eventMeshRuntime "+runtimeName, + "StatefulSet.Namespace", found.Namespace, "StatefulSet.Name", found.Name) + } else { + r.Logger.Info("Successfully update "+runtimeName, + "StatefulSet.Namespace", found.Namespace, "StatefulSet.Name", found.Name) + } + time.Sleep(time.Duration(1) * time.Second) + } + } + } + podList := &corev1.PodList{} + labelSelector := labels.SelectorFromSet(getLabels()) + listOps := &client.ListOptions{ + Namespace: eventMeshRuntime.Namespace, + LabelSelector: labelSelector, + } + err = r.Client.List(context.TODO(), podList, listOps) + if err != nil { + r.Logger.Error(err, "Failed to list pods.", + "eventMeshRuntime.Namespace", eventMeshRuntime.Namespace, "eventMeshRuntime.Name", eventMeshRuntime.Name) + return reconcile.Result{}, err + } + + podNames := getRuntimePodNames(podList.Items) + r.Logger.Info(fmt.Sprintf("Status.Nodes = %s", eventMeshRuntime.Status.Nodes)) + r.Logger.Info(fmt.Sprintf("podNames = %s", podNames)) + // Ensure every pod is in running phase + for _, pod := range podList.Items { + if !reflect.DeepEqual(pod.Status.Phase, corev1.PodRunning) { + r.Logger.Info("pod " + pod.Name + " phase is " + string(pod.Status.Phase) + ", wait for a moment...") + } + } + + if podNames != nil { + eventMeshRuntime.Status.Nodes = podNames + r.Logger.Info(fmt.Sprintf("eventMeshRuntime.Status.Nodes = %s", eventMeshRuntime.Status.Nodes)) + // Update status.Size if needed + if eventMeshRuntime.Spec.Size != eventMeshRuntime.Status.Size { + r.Logger.Info("eventMeshRuntime.Status.Size = " + strconv.Itoa(eventMeshRuntime.Status.Size)) + r.Logger.Info("eventMeshRuntime.Spec.Size = " + strconv.Itoa(eventMeshRuntime.Spec.Size)) + eventMeshRuntime.Status.Size = eventMeshRuntime.Spec.Size + err = r.Client.Status().Update(context.TODO(), eventMeshRuntime) + if err != nil { + r.Logger.Error(err, "Failed to update eventMeshRuntime Size status.") + } + } + + // Update status.Nodes if needed + if !reflect.DeepEqual(podNames, eventMeshRuntime.Status.Nodes) { + err = r.Client.Status().Update(context.TODO(), eventMeshRuntime) + if err != nil { + r.Logger.Error(err, "Failed to update eventMeshRuntime Nodes status.") + } + } + } else { + r.Logger.Error(err, "Not found eventmesh runtime pods") + } + + runningEventMeshRuntimeNum := getRunningRuntimeNum(podList.Items) + if runningEventMeshRuntimeNum == eventMeshRuntime.Spec.Size { + share.IsEventMeshRuntimeInitialized = true + } + + r.Logger.Info("Successful reconciliation!") + + return reconcile.Result{Requeue: true, RequeueAfter: time.Duration(share.RequeueAfterSecond) * time.Second}, nil +} + +func getRunningRuntimeNum(pods []corev1.Pod) int { + var num = 0 + for _, pod := range pods { + if reflect.DeepEqual(pod.Status.Phase, corev1.PodRunning) { + num++ + } + } + return num +} + +func getRuntimePodNames(pods []corev1.Pod) []string { + var podNames []string + for _, pod := range pods { + podNames = append(podNames, pod.Name) + } + return podNames +} + +var GroupNum = 0 + +func (r *RuntimeReconciler) getEventMeshRuntimeStatefulSet(runtime *eventmeshoperatorv1.Runtime, groupIndex int, replicaIndex int) *appsv1.StatefulSet { + var statefulSetName string + var a int32 = 1 + var c = &a + if replicaIndex == 0 { + statefulSetName = runtime.Name + "-" + strconv.Itoa(groupIndex) + "-a" + } else { + statefulSetName = runtime.Name + "-" + strconv.Itoa(groupIndex) + "-r-" + strconv.Itoa(replicaIndex) + } + label := getLabels() + deployment := &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: statefulSetName, + Namespace: runtime.Namespace, + }, + Spec: appsv1.StatefulSetSpec{ + Replicas: c, + Selector: &metav1.LabelSelector{ + MatchLabels: label, + }, + UpdateStrategy: appsv1.StatefulSetUpdateStrategy{ + Type: appsv1.RollingUpdateStatefulSetStrategyType, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: label, + }, + Spec: corev1.PodSpec{ + DNSPolicy: runtime.Spec.RuntimePodTemplate.Template.Spec.DNSPolicy, + Affinity: runtime.Spec.RuntimePodTemplate.Template.Spec.Affinity, + Tolerations: runtime.Spec.RuntimePodTemplate.Template.Spec.Tolerations, + NodeSelector: runtime.Spec.RuntimePodTemplate.Template.Spec.NodeSelector, + PriorityClassName: runtime.Spec.RuntimePodTemplate.Template.Spec.PriorityClassName, + HostNetwork: runtime.Spec.RuntimePodTemplate.Template.Spec.HostNetwork, + Containers: []corev1.Container{{ + Resources: runtime.Spec.RuntimePodTemplate.Template.Spec.Containers[0].Resources, + Image: runtime.Spec.RuntimePodTemplate.Template.Spec.Containers[0].Image, + Name: runtime.Spec.RuntimePodTemplate.Template.Spec.Containers[0].Name, + SecurityContext: getContainerSecurityContext(runtime), + ImagePullPolicy: runtime.Spec.RuntimePodTemplate.Template.Spec.Containers[0].ImagePullPolicy, + Ports: runtime.Spec.RuntimePodTemplate.Template.Spec.Containers[0].Ports, + VolumeMounts: runtime.Spec.RuntimePodTemplate.Template.Spec.Containers[0].VolumeMounts, + }}, + Volumes: runtime.Spec.RuntimePodTemplate.Template.Spec.Volumes, + SecurityContext: getRuntimePodSecurityContext(runtime), + }, + }, + }, + } + _ = controllerutil.SetControllerReference(runtime, deployment, r.Scheme) + return deployment +} + +func getRuntimePodSecurityContext(runtime *eventmeshoperatorv1.Runtime) *corev1.PodSecurityContext { + var securityContext = corev1.PodSecurityContext{} + if runtime.Spec.PodSecurityContext != nil { + securityContext = *runtime.Spec.PodSecurityContext + } + return &securityContext +} + +func getContainerSecurityContext(runtime *eventmeshoperatorv1.Runtime) *corev1.SecurityContext { + var securityContext = corev1.SecurityContext{} + if runtime.Spec.ContainerSecurityContext != nil { + securityContext = *runtime.Spec.ContainerSecurityContext + } + return &securityContext +} + +func getLabels() map[string]string { + return map[string]string{"app": "eventmesh-runtime"} +} diff --git a/eventmesh-operator/controllers/suite_test.go b/eventmesh-operator/controllers/suite_test.go new file mode 100644 index 0000000000..5f4522eab7 --- /dev/null +++ b/eventmesh-operator/controllers/suite_test.go @@ -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 controllers + +import ( + "path/filepath" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + eventmeshoperatorv1 "github.com/apache/eventmesh/eventmesh-operator/api/v1" + //+kubebuilder:scaffold:imports +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. + +var cfg *rest.Config +var k8sClient client.Client +var testEnv *envtest.Environment + +func TestAPIs(t *testing.T) { + RegisterFailHandler(Fail) + + RunSpecs(t, "Controller Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, + ErrorIfCRDPathMissing: true, + } + + var err error + // cfg is defined in this file globally. + cfg, err = testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = eventmeshoperatorv1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + //+kubebuilder:scaffold:scheme + + k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(k8sClient).NotTo(BeNil()) + +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/eventmesh-operator/eventmesh-operator.md b/eventmesh-operator/eventmesh-operator.md new file mode 100644 index 0000000000..cda91fcce9 --- /dev/null +++ b/eventmesh-operator/eventmesh-operator.md @@ -0,0 +1,185 @@ +## Environment + +### Prerequisite + +- docker +- golang +- kubernetes + +### Install + +- [Install the Operator SDK](https://v1-5-x.sdk.operatorframework.io/docs/installation/) + +## Build Operator: + +- Create an Operator Project + +``` +operator-sdk init --domain eventmesh --repo github.com/apache/eventmesh/eventmesh-operator + +Directory Structure: +. +├── Dockerfile +├── Makefile +├── PROJECT +├── README.md +├── config +│   ├── default +│   │   ├── kustomization.yaml +│   │   ├── manager_auth_proxy_patch.yaml +│   │   └── manager_config_patch.yaml +│   ├── manager +│   │   ├── kustomization.yaml +│   │   └── manager.yaml +│   ├── manifests +│   │   └── kustomization.yaml +│   ├── prometheus +│   │   ├── kustomization.yaml +│   │   └── monitor.yaml +│   ├── rbac +│   │   ├── auth_proxy_client_clusterrole.yaml +│   │   ├── auth_proxy_role.yaml +│   │   ├── auth_proxy_role_binding.yaml +│   │   ├── auth_proxy_service.yaml +│   │   ├── kustomization.yaml +│   │   ├── leader_election_role.yaml +│   │   ├── leader_election_role_binding.yaml +│   │   ├── role_binding.yaml +│   │   └── service_account.yaml +│   └── scorecard +│   ├── bases +│   │   └── config.yaml +│   ├── kustomization.yaml +│   └── patches +│   ├── basic.config.yaml +│   └── olm.config.yaml +├── go.mod +├── go.sum +├── hack +│   └── boilerplate.go.txt +└── main.go +``` +**Makefile**: make targets for building and deploying your controller +**PROJECT**: automatically generated project metadata. +**go.mod**: a new Go module matching our project, with basic dependencies +**config/default**: contains for starting the controller in a standard configuration. +**config/manager**: launch your controllers as pods in the cluster +**config/rbac**: permissions required to run your controllers under their own service account + +- Create api、resource、controller + +``` +operator-sdk create api --group eventmesh --version v1 --kind EventMeshOperator --resource --controller + +Directory Structure: +. +├── Dockerfile +├── Makefile +├── PROJECT +├── README.md +├── api +│   └── v1 +│   ├── eventmeshoperator_types.go +│   ├── groupversion_info.go +│   └── zz_generated.deepcopy.go +├── bin +│   └── controller-gen +├── config +│   ├── crd +│   │   ├── kustomization.yaml +│   │   ├── kustomizeconfig.yaml +│   │   └── patches +│   │   ├── cainjection_in_eventmeshoperators.yaml +│   │   └── webhook_in_eventmeshoperators.yaml +│   ├── default +│   │   ├── kustomization.yaml +│   │   ├── manager_auth_proxy_patch.yaml +│   │   └── manager_config_patch.yaml +│   ├── manager +│   │   ├── kustomization.yaml +│   │   └── manager.yaml +│   ├── manifests +│   │   └── kustomization.yaml +│   ├── prometheus +│   │   ├── kustomization.yaml +│   │   └── monitor.yaml +│   ├── rbac +│   │   ├── auth_proxy_client_clusterrole.yaml +│   │   ├── auth_proxy_role.yaml +│   │   ├── auth_proxy_role_binding.yaml +│   │   ├── auth_proxy_service.yaml +│   │   ├── eventmeshoperator_editor_role.yaml +│   │   ├── eventmeshoperator_viewer_role.yaml +│   │   ├── kustomization.yaml +│   │   ├── leader_election_role.yaml +│   │   ├── leader_election_role_binding.yaml +│   │   ├── role_binding.yaml +│   │   └── service_account.yaml +│   ├── samples +│   │   ├── grouptest_v1_eventmeshoperator.yaml +│   │   └── kustomization.yaml +│   └── scorecard +│   ├── bases +│   │   └── config.yaml +│   ├── kustomization.yaml +│   └── patches +│   ├── basic.config.yaml +│   └── olm.config.yaml +├── controllers +│   ├── eventmeshoperator_controller.go +│   └── suite_test.go +├── go.mod +├── go.sum +├── hack +│   └── boilerplate.go.txt +└── main.go +``` +**eventmeshoperator_types.go**: custom CRD corresponding struct place. +**groupversion_info.go**: groupVersion (GV) defines and registers CRD with Scheme. +**zz_generated.deepcopy.go**: GVR DeepCopy method automatically generated. +**crd**: the relevant Yaml collection for deploying CRD. +**default**: a default Yaml collection of the Operator is deployed using Kustomize, which is based on crd, rbac, and manager. +**manager**: deploy the associated Yaml collection of operators. +**prometheus**: the Operator runs and monitors the associated Yaml collections. +**rbac**: Yaml collections associated with RBAC permissions required for Operator deployment. +**samples**: deploy Yaml for a CR sample. +**controllers**: developers implement their own logic, and ventmeshoperator_controller.go is the file that completes the control logic. + +- Controller TODO +``` +func (r *EventMeshOperatorReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + _ = log.FromContext(ctx) + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} +``` + +- Register to CRD: +``` +make generate +make manifests +``` + +- Builder IMG +``` +make docker-builder IMG= +make deploy IMG= +``` + +## EventMesh Components + +- EventMesh-runtime: Core Components, Runtime Modules + +- EventMesh-sdks: Supports HTTP, TCP, GRPC protocols + +- EventMesh-connectors: Connectors, Connecting Inserts + +- EventMesh-storage: Storage Module + +- EventMesh-workflow: EventMesh Workflow + +- EventMesh-dashboard: EventMesh Dashboard + +... \ No newline at end of file diff --git a/eventmesh-operator/go.mod b/eventmesh-operator/go.mod new file mode 100644 index 0000000000..95595636c4 --- /dev/null +++ b/eventmesh-operator/go.mod @@ -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. +// + +module github.com/apache/eventmesh/eventmesh-operator + +go 1.19 + +require ( + github.com/go-logr/logr v1.2.3 + github.com/onsi/ginkgo/v2 v2.6.0 + github.com/onsi/gomega v1.24.1 + k8s.io/api v0.26.1 + k8s.io/apimachinery v0.26.1 + k8s.io/client-go v0.26.1 + sigs.k8s.io/controller-runtime v0.14.1 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-logr/zapr v1.2.3 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/swag v0.19.14 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/imdario/mergo v0.3.6 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.6 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 // indirect + golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/term v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect + golang.org/x/time v0.3.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiextensions-apiserver v0.26.0 // indirect + k8s.io/component-base v0.26.0 // indirect + k8s.io/klog/v2 v2.80.1 // indirect + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect + k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) + +replace github.com/apache/eventmesh/eventmesh-operator/ => ./ diff --git a/eventmesh-operator/go.sum b/eventmesh-operator/go.sum new file mode 100644 index 0000000000..591da7349f --- /dev/null +++ b/eventmesh-operator/go.sum @@ -0,0 +1,621 @@ +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= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/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.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +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/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +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.4.1/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.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +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/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= +github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +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/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= +github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +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/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +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-20181114220301-adae6a3d119a/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 h1:Frnccbp+ok2GkUS2tC84yAq/U9Vg+0sIO7aRL3T4Xnc= +golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +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-20190227155943-e225da77a7e6/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/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= +gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +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.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +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.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +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.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/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-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= +k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= +k8s.io/apiextensions-apiserver v0.26.0 h1:Gy93Xo1eg2ZIkNX/8vy5xviVSxwQulsnUdQ00nEdpDo= +k8s.io/apiextensions-apiserver v0.26.0/go.mod h1:7ez0LTiyW5nq3vADtK6C3kMESxadD51Bh6uz3JOlqWQ= +k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= +k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= +k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU= +k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE= +k8s.io/component-base v0.26.0 h1:0IkChOCohtDHttmKuz+EP3j3+qKmV55rM9gIFTXA7Vs= +k8s.io/component-base v0.26.0/go.mod h1:lqHwlfV1/haa14F/Z5Zizk5QmzaVf23nQzCwVOQpfC8= +k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/controller-runtime v0.14.1 h1:vThDes9pzg0Y+UbCPY3Wj34CGIYPgdmspPm2GIpxpzM= +sigs.k8s.io/controller-runtime v0.14.1/go.mod h1:GaRkrY8a7UZF0kqFFbUKG7n9ICiTY5T55P1RiE3UZlU= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/eventmesh-operator/hack/boilerplate.go.txt b/eventmesh-operator/hack/boilerplate.go.txt new file mode 100644 index 0000000000..d973dcedae --- /dev/null +++ b/eventmesh-operator/hack/boilerplate.go.txt @@ -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-operator/main.go b/eventmesh-operator/main.go new file mode 100644 index 0000000000..ed1c4eb483 --- /dev/null +++ b/eventmesh-operator/main.go @@ -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 main + +import ( + "flag" + "github.com/apache/eventmesh/eventmesh-operator/controllers/eventmesh_connectors" + "github.com/apache/eventmesh/eventmesh-operator/controllers/eventmesh_runtime" + "k8s.io/apimachinery/pkg/runtime" + "os" + + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + // to ensure that exec-entrypoint and run can make use of them. + _ "k8s.io/client-go/plugin/pkg/client/auth" + + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + + eventmeshoperatorv1 "github.com/apache/eventmesh/eventmesh-operator/api/v1" + //+kubebuilder:scaffold:imports +) + +//+kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups="",resources=events,verbs=create;patch + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + + utilruntime.Must(eventmeshoperatorv1.AddToScheme(scheme)) + //+kubebuilder:scaffold:scheme +} + +func main() { + var metricsAddr string + var enableLeaderElection bool + var probeAddr string + var watchNamespace string + flag.StringVar(&watchNamespace, "watch-namespace", os.Getenv("WATCH_NAMESPACE"), "The namespace to watch, if not specified, all namespaces will be watched") + flag.StringVar(&metricsAddr, "metrics-bind-address", ":9020", "The address the metric endpoint binds to.") + flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + flag.BoolVar(&enableLeaderElection, "leader-elect", false, + "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + opts := zap.Options{ + Development: true, + } + opts.BindFlags(flag.CommandLine) + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + Scheme: scheme, + MetricsBindAddress: metricsAddr, + Port: 9443, + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "bcdc2f43.eventmesh", + Namespace: watchNamespace, + // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily + // when the Manager ends. This requires the binary to immediately end when the + // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly + // speeds up voluntary leader transitions as the new leader don't have to wait + // LeaseDuration time first. + // + // In the default scaffold provided, the program ends immediately after + // the manager stops, so would be fine to enable this option. However, + // if you are doing or is intended to do any operation such as perform cleanups + // after the manager stops then its usage might be unsafe. + // LeaderElectionReleaseOnCancel: true, + }) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + // Setup all Controllers + if err := eventmesh_runtime.SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to add eventmesh_runtime controller to manager") + os.Exit(1) + } + + if err := eventmesh_connectors.SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to add eventmesh_connectors controller to manager") + os.Exit(1) + } + + //+kubebuilder:scaffold:builder + if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up health check") + os.Exit(1) + } + if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up ready check") + os.Exit(1) + } + + setupLog.Info("starting manager") + if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} diff --git a/eventmesh-operator/share/share.go b/eventmesh-operator/share/share.go new file mode 100644 index 0000000000..1027bba580 --- /dev/null +++ b/eventmesh-operator/share/share.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 share + +var ( + // IsEventMeshRuntimeInitialized is whether the runtime list is initialized + IsEventMeshRuntimeInitialized = false +) + +const ( + // WaitForRuntimePodNameReadyInSecond is the time connector sleep for waiting runtime ready in second + WaitForRuntimePodNameReadyInSecond = 1 + // RequeueAfterSecond is a universal interval of the reconcile function + RequeueAfterSecond = 6 +) diff --git a/eventmesh-protocol-plugin/build.gradle b/eventmesh-protocol-plugin/build.gradle new file mode 100644 index 0000000000..d973dcedae --- /dev/null +++ b/eventmesh-protocol-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-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 index 2d6f7bd559..735d6ea41a 100644 --- 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 @@ -47,12 +47,10 @@ public class ProtocolPluginFactory { public static ProtocolAdaptor getProtocolAdaptor(String protocolType) { ProtocolAdaptor protocolAdaptor = PROTOCOL_ADAPTOR_MAP.computeIfAbsent( protocolType, - (type) -> EventMeshExtensionFactory.getExtension(ProtocolAdaptor.class, type) - ); + (type) -> EventMeshExtensionFactory.getExtension(ProtocolAdaptor.class, type)); if (protocolAdaptor == null) { throw new IllegalArgumentException( - String.format("Cannot find the Protocol adaptor: %s", protocolType) - ); + String.format("Cannot find the Protocol adaptor: %s", protocolType)); } return protocolAdaptor; } diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-api/src/test/java/org/apache/eventmesh/protocol/api/MockProtocolAdaptorImpl.java b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/test/java/org/apache/eventmesh/protocol/api/MockProtocolAdaptorImpl.java new file mode 100644 index 0000000000..648f3e2225 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/test/java/org/apache/eventmesh/protocol/api/MockProtocolAdaptorImpl.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.protocol.api; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; + +import java.util.List; + +import io.cloudevents.CloudEvent; + +public class MockProtocolAdaptorImpl implements ProtocolAdaptor { + + @Override + public CloudEvent toCloudEvent(ProtocolTransportObject protocol) throws ProtocolHandleException { + return null; + } + + @Override + public List toBatchCloudEvent(ProtocolTransportObject protocol) throws ProtocolHandleException { + return null; + } + + @Override + public ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) throws ProtocolHandleException { + return null; + } + + @Override + public String getProtocolType() { + return null; + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-api/src/test/java/org/apache/eventmesh/protocol/api/ProtocolPluginFactoryTest.java b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/test/java/org/apache/eventmesh/protocol/api/ProtocolPluginFactoryTest.java new file mode 100644 index 0000000000..1aa35e0c65 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/test/java/org/apache/eventmesh/protocol/api/ProtocolPluginFactoryTest.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.protocol.api; + +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.google.common.collect.Maps; + +public class ProtocolPluginFactoryTest { + + private static final String PROTOCOL_TYPE_NAME = "testProtocolType"; + + private static final String MODIFIERS = "modifiers"; + + private static final String PROTOCOL_ADAPTER_MAP = "PROTOCOL_ADAPTOR_MAP"; + + @Test + public void testGetProtocolAdaptor() throws IllegalAccessException, NoSuchFieldException { + Map> mockProtocolAdaptorMap = + new ConcurrentHashMap<>(16); + ProtocolAdaptor expectedAdaptor = new MockProtocolAdaptorImpl(); + mockProtocolAdaptorMap.put(PROTOCOL_TYPE_NAME, expectedAdaptor); + + Field field = ProtocolPluginFactory.class.getDeclaredField(PROTOCOL_ADAPTER_MAP); + field.setAccessible(true); + Field modifiersField = Field.class.getDeclaredField(MODIFIERS); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + final Object originMap = field.get(null); + field.set(null, mockProtocolAdaptorMap); + + ProtocolAdaptor actualAdaptor = ProtocolPluginFactory.getProtocolAdaptor(PROTOCOL_TYPE_NAME); + Assertions.assertEquals(expectedAdaptor, actualAdaptor); + + field.set(null, Maps.newHashMap()); + ProtocolAdaptor adaptor = ProtocolPluginFactory.getProtocolAdaptor(PROTOCOL_TYPE_NAME); + Assertions.assertEquals(adaptor.getClass(), MockProtocolAdaptorImpl.class); + + field.set(null, originMap); + } + + @Test + public void testGetProtocolAdaptorThrowsException() { + Assertions.assertThrows(IllegalArgumentException.class, () -> ProtocolPluginFactory.getProtocolAdaptor("empty_type_name")); + } +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-api/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.protocol.api.ProtocolAdaptor new file mode 100644 index 0000000000..6dd5895bff --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-api/src/test/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. +# +testProtocolType=org.apache.eventmesh.protocol.api.MockProtocolAdaptorImpl \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/build.gradle b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/build.gradle index 5a1bfd5c0e..f377191c30 100644 --- a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/build.gradle +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/build.gradle @@ -24,4 +24,11 @@ dependencies { exclude group: "com.google.protobuf", module: "protobuf-java" } implementation("com.google.protobuf:protobuf-java:3.21.5") + implementation "io.cloudevents:cloudevents-protobuf" + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' } 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 index 43e04ea09c..ddbfe44eca 100644 --- 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 @@ -19,10 +19,9 @@ 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.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.common.BatchEventMeshCloudEventWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventWrapper; 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; @@ -30,14 +29,12 @@ 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.grpc.GrpcEventMeshCloudEventProtocolResolver; 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.util.HashMap; import java.util.List; import java.util.Map; @@ -74,9 +71,9 @@ public CloudEvent toCloudEvent(ProtocolTransportObject cloudEvent) throws Protoc 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 if (cloudEvent instanceof EventMeshCloudEventWrapper) { + EventMeshCloudEventWrapper ce = (EventMeshCloudEventWrapper) cloudEvent; + return GrpcEventMeshCloudEventProtocolResolver.buildEvent(ce.getMessage()); } else { throw new ProtocolHandleException(String.format("protocol class: %s", cloudEvent.getClass())); } @@ -90,26 +87,24 @@ 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)); + switch (RequestCode.get(Integer.parseInt(requestCode))) { + case MSG_BATCH_SEND: + return SendMessageBatchProtocolResolver.buildEvent(header, body); + case MSG_BATCH_SEND_V2: + return SendMessageBatchV2ProtocolResolver.buildEvent(header, body); + case MSG_SEND_SYNC: + case MSG_SEND_ASYNC: + return SendMessageRequestProtocolResolver.buildEvent(header, body); + default: + 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); + public List toBatchCloudEvent(ProtocolTransportObject protocol) throws ProtocolHandleException { + if (protocol instanceof BatchEventMeshCloudEventWrapper) { + CloudEventBatch cloudEventBatch = ((BatchEventMeshCloudEventWrapper) protocol).getMessage(); + return GrpcEventMeshCloudEventProtocolResolver.buildBatchEvents(cloudEventBatch); } else { throw new ProtocolHandleException(String.format("protocol class: %s", protocol.getClass())); } @@ -119,36 +114,38 @@ public List toBatchCloudEvent(ProtocolTransportObject protocol) public ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) throws ProtocolHandleException { Preconditions.checkNotNull(cloudEvent, "cloudEvent cannot be null"); String protocolDesc = Objects.requireNonNull(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 = - Objects.requireNonNull(EventFormatProvider.getInstance() - .resolveFormat(JsonFormat.CONTENT_TYPE)).serialize(cloudEvent); - map.put("content", new String(eventByte, Constants.DEFAULT_CHARSET)); - 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(Constants.PROTOCOL_GRPC, protocolDesc)) { - return GrpcMessageProtocolResolver.buildSimpleMessage(cloudEvent); - } else { - throw new ProtocolHandleException(String.format("Unsupported protocolDesc: %s", protocolDesc)); + switch (protocolDesc) { + case "http": + HttpCommand httpCommand = new HttpCommand(); + Body body = new Body() { + + final Map map = new HashMap<>(); + + @Override + public Map toMap() { + byte[] eventByte = + Objects.requireNonNull(EventFormatProvider.getInstance() + .resolveFormat(JsonFormat.CONTENT_TYPE)).serialize(cloudEvent); + map.put("content", new String(eventByte, Constants.DEFAULT_CHARSET)); + return map; + } + }; + body.toMap(); + httpCommand.setBody(body); + return httpCommand; + case "tcp": + 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; + case CloudEventsProtocolConstant.PROTOCOL_DESC_GRPC_CLOUD_EVENT: + return GrpcEventMeshCloudEventProtocolResolver.buildEventMeshCloudEvent(cloudEvent); + default: + throw new ProtocolHandleException(String.format("Unsupported protocolDesc: %s", protocolDesc)); } } 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 index 7c26920626..476430afa9 100644 --- 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 @@ -19,5 +19,8 @@ public enum CloudEventsProtocolConstant { ; + public static final String PROTOCOL_NAME = "cloudevents"; + + public static final String PROTOCOL_DESC_GRPC_CLOUD_EVENT = "grpc-cloud-event"; } diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/grpc/GrpcEventMeshCloudEventProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/grpc/GrpcEventMeshCloudEventProtocolResolver.java new file mode 100644 index 0000000000..a00d1852a9 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/grpc/GrpcEventMeshCloudEventProtocolResolver.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.protocol.cloudevents.resolver.grpc; + +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventWrapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import io.cloudevents.core.format.EventFormat; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.protobuf.ProtobufFormat; + +import com.google.protobuf.InvalidProtocolBufferException; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GrpcEventMeshCloudEventProtocolResolver { + + private static final EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(ProtobufFormat.PROTO_CONTENT_TYPE); + + public static io.cloudevents.CloudEvent buildEvent(CloudEvent cloudEvent) { + return Objects.requireNonNull(eventFormat).deserialize(cloudEvent.toByteArray()); + } + + public static List buildBatchEvents(CloudEventBatch cloudEventBatch) { + if (cloudEventBatch == null || cloudEventBatch.getEventsCount() < 1) { + return new ArrayList<>(0); + } + return cloudEventBatch.getEventsList().stream().map(cloudEvent -> Objects.requireNonNull(eventFormat).deserialize(cloudEvent.toByteArray())) + .collect(Collectors.toList()); + } + + public static EventMeshCloudEventWrapper buildEventMeshCloudEvent(io.cloudevents.CloudEvent cloudEvent) { + if (null == cloudEvent) { + return new EventMeshCloudEventWrapper(null); + } + try { + return new EventMeshCloudEventWrapper(CloudEvent.parseFrom(Objects.requireNonNull(eventFormat).serialize(cloudEvent))); + } catch (InvalidProtocolBufferException e) { + log.error("Build Event Mesh CloudEvent from io.cloudevents.CloudEvent error", e); + } + return null; + } +} 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 deleted file mode 100644 index be1d741a3f..0000000000 --- a/eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/src/main/java/org/apache/eventmesh/protocol/cloudevents/resolver/grpc/GrpcMessageProtocolResolver.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.protocol.cloudevents.resolver.grpc; - -import org.apache.eventmesh.common.Constants; -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.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import io.cloudevents.CloudEvent; -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, Constants.CONTENT_TYPE_CLOUDEVENTS_JSON); - EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(contentType); - CloudEvent event = Objects.requireNonNull(eventFormat).deserialize(cloudEventJson.getBytes(Constants.DEFAULT_CHARSET)); - - RequestHeader header = message.getHeader(); - - String seqNum = getEventExtensionIfAbsent(message.getSeqNum(), event, ProtocolKey.SEQ_NUM); - String uniqueId = getEventExtensionIfAbsent(message.getUniqueId(), event, ProtocolKey.UNIQUE_ID); - String ttl = getEventExtensionIfAbsent(message.getTtl(), event, ProtocolKey.TTL); - String producerGroup = getEventExtensionIfAbsent(message.getProducerGroup(), event, ProtocolKey.PRODUCERGROUP); - String topic = StringUtils.defaultIfEmpty(message.getTopic(), event.getSubject()); - - CloudEventBuilder eventBuilder = builderCloudEventBuilder(header, event, seqNum, uniqueId, producerGroup, ttl, - topic); - - message.getPropertiesMap().forEach(eventBuilder::withExtension); - - return eventBuilder.build(); - } - - public static SimpleMessageWrapper buildSimpleMessage(CloudEvent cloudEvent) { - String env = getEventExtensionOrDefault(cloudEvent, ProtocolKey.ENV, "env"); - String idc = getEventExtensionOrDefault(cloudEvent, ProtocolKey.IDC, "idc"); - String ip = getEventExtensionOrDefault(cloudEvent, ProtocolKey.IP, "127.0.0.1"); - String pid = getEventExtensionOrDefault(cloudEvent, ProtocolKey.PID, "123"); - String sys = getEventExtensionOrDefault(cloudEvent, ProtocolKey.SYS, "sys123"); - String userName = getEventExtensionOrDefault(cloudEvent, ProtocolKey.USERNAME, "user"); - String passwd = getEventExtensionOrDefault(cloudEvent, ProtocolKey.PASSWD, "pass"); - String language = getEventExtensionOrDefault(cloudEvent, ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA); - String protocol = getEventExtensionOrDefault(cloudEvent, ProtocolKey.PROTOCOL_TYPE, "protocol"); - String protocolDesc = getEventExtensionOrDefault(cloudEvent, ProtocolKey.PROTOCOL_DESC, "protocolDesc"); - String protocolVersion = getEventExtensionOrDefault(cloudEvent, ProtocolKey.PROTOCOL_VERSION, "1.0"); - String seqNum = getEventExtensionOrDefault(cloudEvent, ProtocolKey.SEQ_NUM, ""); - String uniqueId = getEventExtensionOrDefault(cloudEvent, ProtocolKey.UNIQUE_ID, ""); - String producerGroup = getEventExtensionOrDefault(cloudEvent, ProtocolKey.PRODUCERGROUP, "producerGroup"); - String ttl = getEventExtensionOrDefault(cloudEvent, ProtocolKey.TTL, "3000"); - - 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 = Objects.requireNonNull(cloudEvent.getDataContentType()); - EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(contentType); - - SimpleMessage.Builder messageBuilder = SimpleMessage.newBuilder() - .setHeader(header) - .setContent(new String(Objects.requireNonNull(eventFormat).serialize(cloudEvent), Constants.DEFAULT_CHARSET)) - .setProducerGroup(producerGroup) - .setSeqNum(seqNum) - .setUniqueId(uniqueId) - .setTopic(cloudEvent.getSubject()) - .setTtl(ttl) - .putProperties(ProtocolKey.CONTENT_TYPE, contentType); - - for (String key : cloudEvent.getExtensionNames()) { - messageBuilder.putProperties(key, Objects.requireNonNull(cloudEvent.getExtension(key)).toString()); - } - - return new SimpleMessageWrapper(messageBuilder.build()); - } - - 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, Constants.CONTENT_TYPE_CLOUDEVENTS_JSON); - EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(contentType); - CloudEvent event = Objects.requireNonNull(eventFormat).deserialize(cloudEventJson.getBytes(Constants.DEFAULT_CHARSET)); - - String seqNum = getEventExtensionIfAbsent(item.getSeqNum(), event, ProtocolKey.SEQ_NUM); - String uniqueId = getEventExtensionIfAbsent(item.getUniqueId(), event, ProtocolKey.UNIQUE_ID); - String producerGroup = getEventExtensionIfAbsent(batchMessage.getProducerGroup(), event, ProtocolKey.PRODUCERGROUP); - String ttl = getEventExtensionIfAbsent(item.getTtl(), event, ProtocolKey.TTL); - String topic = StringUtils.defaultIfEmpty(batchMessage.getTopic(), event.getSubject()); - - CloudEventBuilder eventBuilder = builderCloudEventBuilder(header, event, seqNum, uniqueId, producerGroup, - ttl, topic); - - item.getPropertiesMap().forEach(eventBuilder::withExtension); - - cloudEvents.add(eventBuilder.build()); - } - return cloudEvents; - } - - private static CloudEventBuilder builderCloudEventBuilder(RequestHeader header, CloudEvent event, String seqNum, - String uniqueId, String producerGroup, String ttl, - String topic) { - String env = getEventExtensionIfAbsent(header.getEnv(), event, ProtocolKey.ENV); - String idc = getEventExtensionIfAbsent(header.getIdc(), event, ProtocolKey.IDC); - String ip = getEventExtensionIfAbsent(header.getIp(), event, ProtocolKey.IP); - String pid = getEventExtensionIfAbsent(header.getPid(), event, ProtocolKey.PID); - String sys = getEventExtensionIfAbsent(header.getSys(), event, ProtocolKey.SYS); - String language = getEventExtensionIfAbsent(header.getLanguage(), event, ProtocolKey.LANGUAGE); - String protocolType = getEventExtensionIfAbsent(header.getProtocolType(), event, ProtocolKey.PROTOCOL_TYPE); - String protocolDesc = getEventExtensionIfAbsent(header.getProtocolDesc(), event, ProtocolKey.PROTOCOL_DESC); - String protocolVersion = getEventExtensionIfAbsent(header.getProtocolVersion(), event, ProtocolKey.PROTOCOL_VERSION); - String username = getEventExtensionIfAbsent(header.getUsername(), event, ProtocolKey.USERNAME); - String passwd = getEventExtensionIfAbsent(header.getPassword(), event, ProtocolKey.PASSWD); - - CloudEventBuilder eventBuilder = CloudEventBuilder.from(event); - - return eventBuilder - .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) - .withSubject(topic); - - } - - private static String getEventExtensionOrDefault(CloudEvent event, String protocolKey, String defaultValue) { - Object extension = event.getExtension(protocolKey); - return Objects.isNull(extension) ? defaultValue : extension.toString(); - } - - private static String getEventExtensionIfAbsent(String value, CloudEvent event, String key) { - return StringUtils.isEmpty(value) ? Objects.requireNonNull(event.getExtension(key)).toString() : value; - } - -} 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 index fd426859fd..8d8b0b2d94 100644 --- 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 @@ -67,13 +67,13 @@ public static CloudEvent buildEvent(Header header, Body body) throws ProtocolHan .deserialize(content.getBytes(Constants.DEFAULT_CHARSET)); 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.ClientInstanceKey.ENV.getKey(), env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC.getKey(), idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP.getKey(), ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID.getKey(), pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS.getKey(), sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME.getKey(), username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD.getKey(), passwd) .withExtension(ProtocolKey.VERSION, version.getVersion()) .withExtension(ProtocolKey.LANGUAGE, language) .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) 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 index 328fbf1278..a803312591 100644 --- 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 @@ -67,13 +67,13 @@ public static CloudEvent buildEvent(Header header, Body body) throws ProtocolHan .deserialize(content.getBytes(Constants.DEFAULT_CHARSET)); 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.ClientInstanceKey.ENV.getKey(), env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC.getKey(), idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP.getKey(), ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID.getKey(), pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS.getKey(), sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME.getKey(), username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD.getKey(), passwd) .withExtension(ProtocolKey.VERSION, version.getVersion()) .withExtension(ProtocolKey.LANGUAGE, language) .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) 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 index 7d35b5d65d..32315938df 100644 --- 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 @@ -64,7 +64,7 @@ public static CloudEvent buildEvent(Header header, String cloudEventJson) // todo:resolve different format EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE); Preconditions - .checkNotNull(eventFormat, "EventFormat: %s is not supported", JsonFormat.CONTENT_TYPE); + .checkNotNull(eventFormat, "EventFormat: %s is not supported", JsonFormat.CONTENT_TYPE); CloudEvent event = eventFormat.deserialize(cloudEventJson.getBytes(StandardCharsets.UTF_8)); cloudEventBuilder = CloudEventBuilder.from(event); header.getProperties().forEach((k, v) -> { diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-grpc/build.gradle b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/build.gradle index ddc11bd95a..822882f404 100644 --- a/eventmesh-protocol-plugin/eventmesh-protocol-grpc/build.gradle +++ b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/build.gradle @@ -24,7 +24,7 @@ repositories { mavenCentral() } -def grpcVersion = '1.42.2' // CURRENT_GRPC_VERSION +def grpcVersion = '1.43.2' // CURRENT_GRPC_VERSION def protobufVersion = '3.21.5' def protocVersion = protobufVersion @@ -36,8 +36,7 @@ dependencies { 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' + testImplementation 'org.junit.jupiter:junit-jupiter:5.6.0' } protobuf { @@ -51,7 +50,3 @@ protobuf { } } } - -test { - useJUnitPlatform() -} \ No newline at end of file diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-cloudevents.proto b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-cloudevents.proto new file mode 100644 index 0000000000..37e07a0b40 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-cloudevents.proto @@ -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. + */ + + + +/** + * CloudEvent Protobuf Format + * + * - Required context attributes are explicitly represented. + * - Optional and Extension context attributes are carried in a map structure. + * - Data may be represented as binary, text, or protobuf messages. + */ + +syntax = "proto3"; + +package org.apache.eventmesh.cloudevents.v1; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; + +option java_package = "org.apache.eventmesh.common.protocol.grpc.cloudevents"; +option java_multiple_files = true; +option java_outer_classname = "EventMeshCloudEvents"; + + +message CloudEvent { + + // -- CloudEvent Context Attributes + + // Required Attributes + string id = 1; + string source = 2; // URI-reference + string spec_version = 3; + string type = 4; + + // Optional & Extension Attributes + map attributes = 5; + + // -- CloudEvent Data (Bytes, Text, or Proto) + oneof data { + bytes binary_data = 6; + string text_data = 7; + google.protobuf.Any proto_data = 8; + } + + /** + * The CloudEvent specification defines + * seven attribute value types... + */ + + message CloudEventAttributeValue { + + oneof attr { + bool ce_boolean = 1; + int32 ce_integer = 2; + string ce_string = 3; + bytes ce_bytes = 4; + string ce_uri = 5; + string ce_uri_ref = 6; + google.protobuf.Timestamp ce_timestamp = 7; + } + } +} + +/** + * CloudEvent Protobuf Batch Format + * + */ + +message CloudEventBatch { + repeated CloudEvent events = 1; +} diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-service.proto b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-service.proto new file mode 100644 index 0000000000..99d57bc514 --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-grpc/src/main/proto/eventmesh-service.proto @@ -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. + */ +syntax = "proto3"; + +package org.apache.eventmesh.cloudevents.v1; + +import "google/protobuf/empty.proto"; +import "eventmesh-cloudevents.proto"; + +option java_package = "org.apache.eventmesh.common.protocol.grpc.cloudevents"; +option java_multiple_files = true; +option java_outer_classname = "EventMeshGrpcService"; + + +service PublisherService { + //publish event + rpc publish(CloudEvent) returns (CloudEvent); + + //publish event with reply + rpc requestReply(CloudEvent) returns (CloudEvent); + + //publish event one way + rpc publishOneWay(CloudEvent) returns (google.protobuf.Empty); + + // publish batch event + rpc batchPublish(CloudEventBatch) returns (CloudEvent); + + //publish batch event one way + rpc batchPublishOneWay(CloudEventBatch) returns (google.protobuf.Empty); +} + +service ConsumerService { + // The subscribed event will be delivered by invoking the webhook url in the Subscription + rpc subscribe(CloudEvent) returns (CloudEvent); + + // The subscribed event will be delivered through stream of Message + rpc subscribeStream(stream CloudEvent) returns (stream CloudEvent); + + rpc unsubscribe(CloudEvent) returns (CloudEvent); +} + +service HeartbeatService { + rpc heartbeat(CloudEvent) returns (CloudEvent); +} 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 index f7cd566b02..a232781ff6 100644 --- 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 @@ -32,6 +32,7 @@ import org.apache.eventmesh.protocol.http.resolver.HttpRequestProtocolResolver; import java.nio.charset.StandardCharsets; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -42,7 +43,6 @@ import com.fasterxml.jackson.core.type.TypeReference; - /** * CloudEvents protocol adaptor, used to transform CloudEvents message to CloudEvents message. * @@ -78,7 +78,7 @@ private CloudEvent deserializeProtocol(String requestURI, HttpEventWrapper httpE @Override public List toBatchCloudEvent(ProtocolTransportObject protocol) throws ProtocolHandleException { - return null; + return Collections.emptyList(); } @Override @@ -99,7 +99,7 @@ public ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) throws Prot // ce data if (null != cloudEvent.getData()) { Map dataContentMap = JsonUtils.parseTypeReferenceObject( - new String(cloudEvent.getData().toBytes(), Constants.DEFAULT_CHARSET), + new String(Objects.requireNonNull(cloudEvent.getData()).toBytes(), Constants.DEFAULT_CHARSET), new TypeReference>() { }); String requestHeader = JsonUtils.toJSONString( 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 index 0e70bd7d5a..08c17ade37 100644 --- 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 @@ -19,13 +19,12 @@ public enum HttpProtocolConstant { ; - public static final String PROTOCOL_NAME = "http"; - public static final String DATA_CONTENT_TYPE = "application/json"; + public static final String PROTOCOL_NAME = "http"; 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_DEFAULT_SUBJECT = ""; public static final String CONSTANTS_KEY_ID = "id"; public static final String CONSTANTS_KEY_SOURCE = "source"; @@ -35,4 +34,9 @@ public enum HttpProtocolConstant { public static final String CONSTANTS_KEY_BODY = "body"; public static final String CONSTANTS_KEY_PATH = "path"; public static final String CONSTANTS_KEY_METHOD = "method"; + + public static final String DATA_CONTENT_TYPE = "Content-Type"; + + public static final String APPLICATION_JSON = "application/json"; + public static final String PROTOBUF = "application/x-protobuf"; } 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 index 186a74e5bc..258723d3c0 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.protocol.http.resolver; -import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; import org.apache.eventmesh.common.utils.JsonUtils; import org.apache.eventmesh.protocol.api.exception.ProtocolHandleException; @@ -30,7 +29,6 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.UUID; import io.cloudevents.CloudEvent; @@ -60,12 +58,14 @@ public static CloudEvent buildEvent(HttpEventWrapper httpEventWrapper) throws Pr String subject = sysHeaderMap.getOrDefault(HttpProtocolConstant.CONSTANTS_KEY_SUBJECT, HttpProtocolConstant.CONSTANTS_DEFAULT_SUBJECT).toString(); + String dataContentType = requestHeaderMap.getOrDefault(HttpProtocolConstant.DATA_CONTENT_TYPE, + HttpProtocolConstant.APPLICATION_JSON).toString(); // with attributes builder.withId(id) .withType(type) .withSource(URI.create(HttpProtocolConstant.CONSTANTS_KEY_SOURCE + ":" + source)) .withSubject(subject) - .withDataContentType(HttpProtocolConstant.DATA_CONTENT_TYPE); + .withDataContentType(dataContentType); // with extensions for (Map.Entry extension : sysHeaderMap.entrySet()) { @@ -81,19 +81,25 @@ public static CloudEvent buildEvent(HttpEventWrapper httpEventWrapper) throws Pr byte[] requestBody = httpEventWrapper.getBody(); - Map requestBodyMap = JsonUtils.parseTypeReferenceObject(new String(requestBody, Constants.DEFAULT_CHARSET), - 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 - return builder.withData(Objects.requireNonNull(JsonUtils.toJSONString(data)).getBytes(StandardCharsets.UTF_8)).build(); + if (StringUtils.equals(dataContentType, HttpProtocolConstant.APPLICATION_JSON)) { + Map requestBodyMap = JsonUtils.parseTypeReferenceObject(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.toJSONString(data).getBytes(StandardCharsets.UTF_8)); + } else if (StringUtils.equals(dataContentType, HttpProtocolConstant.PROTOBUF)) { + // with data + builder = builder.withData(requestBody); + } + return builder.build(); } catch (Exception e) { throw new ProtocolHandleException(e.getMessage(), e); } 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 index a40764d545..b01c6d5503 100644 --- 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 @@ -21,8 +21,8 @@ import org.apache.eventmesh.protocol.api.ProtocolAdaptor; import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class HttpProtocolAdaptorTest { @@ -31,9 +31,9 @@ public void loadPlugin() { ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(HttpProtocolConstant.PROTOCOL_NAME); - Assert.assertNotNull(protocolAdaptor); - Assert.assertEquals( + Assertions.assertNotNull(protocolAdaptor); + Assertions.assertEquals( HttpProtocolConstant.PROTOCOL_NAME, protocolAdaptor.getProtocolType()); - Assert.assertEquals(HttpProtocolAdaptor.class, protocolAdaptor.getClass()); + Assertions.assertEquals(HttpProtocolAdaptor.class, protocolAdaptor.getClass()); } } diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/build.gradle b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/build.gradle index 80e0ecf840..21c60df83e 100644 --- a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/build.gradle +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/build.gradle @@ -22,7 +22,14 @@ dependencies { exclude group: "com.google.protobuf", module: "protobuf-java" } implementation("com.google.protobuf:protobuf-java:3.21.5") + implementation "io.cloudevents:cloudevents-protobuf" testImplementation project(":eventmesh-protocol-plugin:eventmesh-protocol-api") testImplementation "io.cloudevents:cloudevents-core" + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' } 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 index aed652e8f7..8f1f6af786 100644 --- 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 @@ -18,11 +18,11 @@ package org.apache.eventmesh.protocol.meshmessage; import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.enums.EventMeshProtocolType; 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.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.common.BatchEventMeshCloudEventWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventWrapper; 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; @@ -32,18 +32,16 @@ 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.grpc.GrpcEventMeshCloudEventProtocolResolver; 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 java.util.Objects; import io.cloudevents.CloudEvent; @@ -64,21 +62,15 @@ public CloudEvent toCloudEvent(ProtocolTransportObject protocol) throws Protocol 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 if (protocol instanceof EventMeshCloudEventWrapper) { + EventMeshCloudEventWrapper wrapper = (EventMeshCloudEventWrapper) protocol; + return GrpcEventMeshCloudEventProtocolResolver.buildEvent(wrapper.getMessage()); } 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.parseObject(bodyJson, EventMeshMessage.class)); } @@ -87,25 +79,25 @@ 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)); + switch (RequestCode.get(Integer.parseInt(requestCode))) { + case MSG_BATCH_SEND: + return SendMessageBatchProtocolResolver.buildEvent(header, body); + case MSG_BATCH_SEND_V2: + return SendMessageBatchV2ProtocolResolver.buildEvent(header, body); + case MSG_SEND_SYNC: + case MSG_SEND_ASYNC: + return SendMessageRequestProtocolResolver.buildEvent(header, body); + default: + 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); + if (protocol instanceof BatchEventMeshCloudEventWrapper) { + CloudEventBatch cloudEventBatch = ((BatchEventMeshCloudEventWrapper) protocol).getMessage(); + return GrpcEventMeshCloudEventProtocolResolver.buildBatchEvents(cloudEventBatch); } else { throw new ProtocolHandleException(String.format("protocol class: %s", protocol.getClass())); } @@ -115,38 +107,40 @@ public List toBatchCloudEvent(ProtocolTransportObject protocol) thro public ProtocolTransportObject fromCloudEvent(CloudEvent cloudEvent) throws ProtocolHandleException { validateCloudEvent(cloudEvent); String protocolDesc = - cloudEvent.getExtension(Constants.PROTOCOL_DESC) == null ? null : - cloudEvent.getExtension(Constants.PROTOCOL_DESC).toString(); - - if (StringUtils.equals(MeshMessageProtocolConstant.PROTOCOL_DESC_HTTP, protocolDesc)) { - HttpCommand httpCommand = new HttpCommand(); - Body body = new Body() { - final Map map = new HashMap<>(); - - @Override - public Map toMap() { - if (cloudEvent.getData() == null) { + cloudEvent.getExtension(Constants.PROTOCOL_DESC) == null ? null : cloudEvent.getExtension(Constants.PROTOCOL_DESC).toString(); + + switch (Objects.requireNonNull(protocolDesc)) { + case Constants.PROTOCOL_DESC_HTTP: + HttpCommand httpCommand = new HttpCommand(); + Body body = new Body() { + + final Map map = new HashMap<>(); + + @Override + public Map toMap() { + if (cloudEvent.getData() == null) { + return map; + } + map.put(MeshMessageProtocolConstant.PROTOCOL_KEY_CONTENT, + new String(cloudEvent.getData().toBytes(), Constants.DEFAULT_CHARSET)); return map; } - map.put(MeshMessageProtocolConstant.PROTOCOL_KEY_CONTENT, new String(cloudEvent.getData().toBytes(), StandardCharsets.UTF_8)); - return map; - } - }; - body.toMap(); - httpCommand.setBody(body); - return httpCommand; - } else if (StringUtils.equals(MeshMessageProtocolConstant.PROTOCOL_DESC_GRPC, protocolDesc)) { - return GrpcMessageProtocolResolver.buildSimpleMessage(cloudEvent); - } else if (StringUtils.equals(MeshMessageProtocolConstant.PROTOCOL_DESC_TCP, protocolDesc)) { - return TcpMessageProtocolResolver.buildEventMeshMessage(cloudEvent); - } else { - throw new ProtocolHandleException(String.format("Unsupported protocolDesc: %s", protocolDesc)); + }; + body.toMap(); + httpCommand.setBody(body); + return httpCommand; + case Constants.PROTOCOL_DESC_TCP: + return TcpMessageProtocolResolver.buildEventMeshMessage(cloudEvent); + case Constants.PROTOCOL_DESC_GRPC_CLOUD_EVENT: + return GrpcEventMeshCloudEventProtocolResolver.buildEventMeshCloudEvent(cloudEvent); + default: + throw new ProtocolHandleException(String.format("Unsupported protocolDesc: %s", protocolDesc)); } } @Override public String getProtocolType() { - return MeshMessageProtocolConstant.PROTOCOL_NAME; + return EventMeshProtocolType.EVENT_MESH_MESSAGE.protocolTypeName(); } private void validateCloudEvent(CloudEvent cloudEvent) { 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 index d11468b3af..ac9f3d6e46 100644 --- 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 @@ -19,13 +19,8 @@ public enum MeshMessageProtocolConstant { ; - public static final String PROTOCOL_NAME = "eventmeshmessage"; - - public static final String PROTOCOL_DESC_HTTP = "http"; - public static final String PROTOCOL_DESC_GRPC = "grpc"; - - public static final String PROTOCOL_DESC_TCP = "tcp"; + public static final String PROTOCOL_NAME = "eventmeshmessage"; public static final String PROTOCOL_KEY_CONTENT = "content"; } diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/grpc/GrpcEventMeshCloudEventProtocolResolver.java b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/grpc/GrpcEventMeshCloudEventProtocolResolver.java new file mode 100644 index 0000000000..d07760f91e --- /dev/null +++ b/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/grpc/GrpcEventMeshCloudEventProtocolResolver.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.protocol.meshmessage.resolver.grpc; + +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventWrapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import io.cloudevents.core.format.EventFormat; +import io.cloudevents.core.provider.EventFormatProvider; +import io.cloudevents.protobuf.ProtobufFormat; + +import com.google.protobuf.InvalidProtocolBufferException; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GrpcEventMeshCloudEventProtocolResolver { + + private static final EventFormat eventFormat = EventFormatProvider.getInstance().resolveFormat(ProtobufFormat.PROTO_CONTENT_TYPE); + + public static io.cloudevents.CloudEvent buildEvent(CloudEvent cloudEvent) { + if (null == cloudEvent) { + return null; + } + io.cloudevents.CloudEvent event = eventFormat.deserialize(cloudEvent.toByteArray()); + return event; + } + + public static EventMeshCloudEventWrapper buildEventMeshCloudEvent(io.cloudevents.CloudEvent cloudEvent) { + if (null == cloudEvent) { + return new EventMeshCloudEventWrapper(null); + } + try { + return new EventMeshCloudEventWrapper(CloudEvent.parseFrom(eventFormat.serialize(cloudEvent))); + } catch (InvalidProtocolBufferException e) { + log.error("Build Event Mesh CloudEvent from io.cloudevents.CloudEvent error", e); + } + return null; + } + + public static List buildBatchEvents(CloudEventBatch cloudEventBatch) { + if (cloudEventBatch == null || cloudEventBatch.getEventsCount() < 1) { + return new ArrayList<>(0); + } + return cloudEventBatch.getEventsList().stream().map(cloudEvent -> eventFormat.deserialize(cloudEvent.toByteArray())) + .collect(Collectors.toList()); + } + +} 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 deleted file mode 100644 index c0911d0f4c..0000000000 --- a/eventmesh-protocol-plugin/eventmesh-protocol-meshmessage/src/main/java/org/apache/eventmesh/protocol/meshmessage/resolver/grpc/GrpcMessageProtocolResolver.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.protocol.meshmessage.resolver.grpc; - -import org.apache.eventmesh.common.Constants; -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 java.util.Objects; - -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" : getEventExtension(cloudEvent, ProtocolKey.ENV); - String idc = cloudEvent.getExtension(ProtocolKey.IDC) == null ? "idc" : getEventExtension(cloudEvent, ProtocolKey.IDC); - String ip = cloudEvent.getExtension(ProtocolKey.IP) == null ? "ip" : getEventExtension(cloudEvent, ProtocolKey.IP); - String pid = cloudEvent.getExtension(ProtocolKey.PID) == null ? "33" : getEventExtension(cloudEvent, ProtocolKey.PID); - String sys = cloudEvent.getExtension(ProtocolKey.SYS) == null ? "sys" : getEventExtension(cloudEvent, ProtocolKey.SYS); - String userName = cloudEvent.getExtension(ProtocolKey.USERNAME) == null ? "user" : getEventExtension(cloudEvent, ProtocolKey.USERNAME); - String passwd = cloudEvent.getExtension(ProtocolKey.PASSWD) == null ? "pass" : getEventExtension(cloudEvent, ProtocolKey.PASSWD); - String language = cloudEvent.getExtension(ProtocolKey.LANGUAGE) == null ? Constants.LANGUAGE_JAVA : - getEventExtension(cloudEvent, ProtocolKey.LANGUAGE); - String protocol = cloudEvent.getExtension(ProtocolKey.PROTOCOL_TYPE) == null ? "" : - getEventExtension(cloudEvent, ProtocolKey.PROTOCOL_TYPE); - String protocolDesc = cloudEvent.getExtension(ProtocolKey.PROTOCOL_DESC) == null ? "" : - getEventExtension(cloudEvent, ProtocolKey.PROTOCOL_DESC); - String protocolVersion = cloudEvent.getExtension(ProtocolKey.PROTOCOL_VERSION) == null ? "" : - getEventExtension(cloudEvent, ProtocolKey.PROTOCOL_VERSION); - String seqNum = cloudEvent.getExtension(ProtocolKey.SEQ_NUM) == null ? "" : getEventExtension(cloudEvent, ProtocolKey.SEQ_NUM); - String uniqueId = cloudEvent.getExtension(ProtocolKey.UNIQUE_ID) == null ? "" : getEventExtension(cloudEvent, ProtocolKey.UNIQUE_ID); - String producerGroup = cloudEvent.getExtension(ProtocolKey.PRODUCERGROUP) == null ? "" : - getEventExtension(cloudEvent, ProtocolKey.PRODUCERGROUP); - String ttl = cloudEvent.getExtension(ProtocolKey.TTL) == null ? "4000" : getEventExtension(cloudEvent, ProtocolKey.TTL); - - 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(Objects.requireNonNull(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, getEventExtension(cloudEvent, key)); - } - - SimpleMessage simpleMessage = messageBuilder.build(); - - return new SimpleMessageWrapper(simpleMessage); - } - - private static String getEventExtension(CloudEvent event, String protocolKey) { - return Objects.requireNonNull(event.getExtension(protocolKey)).toString(); - } -} 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 index 43259805b4..d7197b6a95 100644 --- 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 @@ -42,7 +42,7 @@ public static CloudEvent buildEvent(Header header, Body body) throws ProtocolHan SendMessageBatchV2RequestBody sendMessageBatchV2RequestBody = (SendMessageBatchV2RequestBody) body; CloudEventBuilder cloudEventBuilder = CloudEventBuilder.fromSpecVersion( - SpecVersion.parse(sendMessageBatchV2RequestHeader.getProtocolVersion())); + SpecVersion.parse(sendMessageBatchV2RequestHeader.getProtocolVersion())); return getBuildCloudEvent(sendMessageBatchV2RequestHeader, sendMessageBatchV2RequestBody, cloudEventBuilder); } catch (Exception e) { @@ -58,13 +58,13 @@ private static CloudEvent getBuildCloudEvent(SendMessageBatchV2RequestHeader sen .withSource(URI.create("/")) .withData(sendMessageBatchV2RequestBody.getMsg().getBytes(Constants.DEFAULT_CHARSET)) .withExtension(ProtocolKey.REQUEST_CODE, sendMessageBatchV2RequestHeader.getCode()) - .withExtension(ProtocolKey.ClientInstanceKey.ENV, sendMessageBatchV2RequestHeader.getEnv()) - .withExtension(ProtocolKey.ClientInstanceKey.IDC, sendMessageBatchV2RequestHeader.getIdc()) - .withExtension(ProtocolKey.ClientInstanceKey.IP, sendMessageBatchV2RequestHeader.getIp()) - .withExtension(ProtocolKey.ClientInstanceKey.PID, sendMessageBatchV2RequestHeader.getPid()) - .withExtension(ProtocolKey.ClientInstanceKey.SYS, sendMessageBatchV2RequestHeader.getSys()) - .withExtension(ProtocolKey.ClientInstanceKey.USERNAME, sendMessageBatchV2RequestHeader.getUsername()) - .withExtension(ProtocolKey.ClientInstanceKey.PASSWD, sendMessageBatchV2RequestHeader.getPasswd()) + .withExtension(ProtocolKey.ClientInstanceKey.ENV.getKey(), sendMessageBatchV2RequestHeader.getEnv()) + .withExtension(ProtocolKey.ClientInstanceKey.IDC.getKey(), sendMessageBatchV2RequestHeader.getIdc()) + .withExtension(ProtocolKey.ClientInstanceKey.IP.getKey(), sendMessageBatchV2RequestHeader.getIp()) + .withExtension(ProtocolKey.ClientInstanceKey.PID.getKey(), sendMessageBatchV2RequestHeader.getPid()) + .withExtension(ProtocolKey.ClientInstanceKey.SYS.getKey(), sendMessageBatchV2RequestHeader.getSys()) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME.getKey(), sendMessageBatchV2RequestHeader.getUsername()) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD.getKey(), sendMessageBatchV2RequestHeader.getPasswd()) .withExtension(ProtocolKey.VERSION, sendMessageBatchV2RequestHeader.getVersion().getVersion()) .withExtension(ProtocolKey.LANGUAGE, sendMessageBatchV2RequestHeader.getLanguage()) .withExtension(ProtocolKey.PROTOCOL_TYPE, sendMessageBatchV2RequestHeader.getProtocolType()) 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 index e41da4ad67..2ad417cf5d 100644 --- 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 @@ -70,13 +70,13 @@ public static CloudEvent buildEvent(Header header, Body body) throws ProtocolHan .withSource(URI.create("/")) .withData(content.getBytes(Constants.DEFAULT_CHARSET)) .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.ClientInstanceKey.ENV.getKey(), env) + .withExtension(ProtocolKey.ClientInstanceKey.IDC.getKey(), idc) + .withExtension(ProtocolKey.ClientInstanceKey.IP.getKey(), ip) + .withExtension(ProtocolKey.ClientInstanceKey.PID.getKey(), pid) + .withExtension(ProtocolKey.ClientInstanceKey.SYS.getKey(), sys) + .withExtension(ProtocolKey.ClientInstanceKey.USERNAME.getKey(), username) + .withExtension(ProtocolKey.ClientInstanceKey.PASSWD.getKey(), passwd) .withExtension(ProtocolKey.VERSION, version.getVersion()) .withExtension(ProtocolKey.LANGUAGE, language) .withExtension(ProtocolKey.PROTOCOL_TYPE, protocolType) 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 index 3f3ef68f97..4e1eac7d84 100644 --- 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 @@ -21,8 +21,8 @@ import org.apache.eventmesh.protocol.api.ProtocolAdaptor; import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class MeshMessageProtocolAdaptorTest { @@ -30,11 +30,10 @@ public class MeshMessageProtocolAdaptorTest { public void loadPlugin() { ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(MeshMessageProtocolConstant.PROTOCOL_NAME); - Assert.assertNotNull(protocolAdaptor); + Assertions.assertNotNull(protocolAdaptor); - Assert.assertEquals( - MeshMessageProtocolConstant.PROTOCOL_NAME, protocolAdaptor.getProtocolType() - ); + Assertions.assertEquals( + MeshMessageProtocolConstant.PROTOCOL_NAME, protocolAdaptor.getProtocolType()); } @Test 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 index 51cf94a372..62d46d7155 100644 --- 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 @@ -21,8 +21,8 @@ import org.apache.eventmesh.protocol.api.ProtocolAdaptor; import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class OpenMessageProtocolAdaptorTest { @@ -31,10 +31,9 @@ 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()); + Assertions.assertNotNull(protocolAdaptor); + Assertions.assertEquals( + OpenMessageProtocolConstant.PROTOCOL_NAME, protocolAdaptor.getProtocolType()); + Assertions.assertEquals(OpenMessageProtocolAdaptor.class, protocolAdaptor.getClass()); } } diff --git a/eventmesh-protocol-plugin/eventmesh-protocol-webhook/src/main/java/org/apache/eventmesh/protocol/webhook/WebHookProtocolAdaptor.java b/eventmesh-protocol-plugin/eventmesh-protocol-webhook/src/main/java/org/apache/eventmesh/protocol/webhook/WebHookProtocolAdaptor.java index b63666a18b..58f8e2aedf 100644 --- a/eventmesh-protocol-plugin/eventmesh-protocol-webhook/src/main/java/org/apache/eventmesh/protocol/webhook/WebHookProtocolAdaptor.java +++ b/eventmesh-protocol-plugin/eventmesh-protocol-webhook/src/main/java/org/apache/eventmesh/protocol/webhook/WebHookProtocolAdaptor.java @@ -25,7 +25,6 @@ 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.HashMap; diff --git a/eventmesh-registry-plugin/build.gradle b/eventmesh-registry-plugin/build.gradle deleted file mode 100644 index 2944f98194..0000000000 --- a/eventmesh-registry-plugin/build.gradle +++ /dev/null @@ -1,16 +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. - */ 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 deleted file mode 100644 index 893f8ff25c..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/exception/RegistryException.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 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 deleted file mode 100644 index 9ef52f8fe5..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-api/src/main/java/org/apache/eventmesh/api/registry/RegistryService.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.api.registry; - -import org.apache.eventmesh.api.exception.RegistryException; -import org.apache.eventmesh.api.registry.bo.EventMeshAppSubTopicInfo; -import org.apache.eventmesh.api.registry.bo.EventMeshServicePubTopicInfo; -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.Collections; -import java.util.List; -import java.util.Map; - -/** - * RegistryService - */ -@EventMeshSPI(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; - - default Map> findEventMeshClientDistributionData( - String clusterName, String group, String purpose) throws RegistryException { - // todo find metadata - return Collections.emptyMap(); - } - - void registerMetadata(Map metadataMap); - - boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws RegistryException; - - boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws RegistryException; - - default EventMeshAppSubTopicInfo findEventMeshAppSubTopicInfoByGroup(String group) throws RegistryException { - return null; - } - - default List findEventMeshServicePubTopicInfos() throws RegistryException { - return Collections.emptyList(); - } -} diff --git a/eventmesh-registry-plugin/eventmesh-registry-consul/build.gradle b/eventmesh-registry-plugin/eventmesh-registry-consul/build.gradle deleted file mode 100644 index ac92c7425c..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-consul/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. - */ - -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" - - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' -} diff --git a/eventmesh-registry-plugin/eventmesh-registry-consul/gradle.properties b/eventmesh-registry-plugin/eventmesh-registry-consul/gradle.properties deleted file mode 100644 index 3ed992f06e..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-consul/gradle.properties +++ /dev/null @@ -1,19 +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. -# - -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 deleted file mode 100644 index 48585686e0..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/java/org/apache/eventmesh/registry/consul/service/ConsulRegistryService.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 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.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -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; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ConsulRegistryService implements RegistryService { - - public static final String IP_PORT_SEPARATOR = ":"; - - private final AtomicBoolean initStatus = new AtomicBoolean(false); - - private final AtomicBoolean startStatus = new AtomicBoolean(false); - - private String consulHost; - - private String consulPort; - - @Getter - private ConsulClient consulClient; - - private String token; - - @Override - public void init() throws RegistryException { - if (initStatus.compareAndSet(false, true)) { - for (String key : ConfigurationContextUtil.KEYS) { - CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); - if (null != commonConfiguration) { - String namesrvAddr = commonConfiguration.getNamesrvAddr(); - 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 { - if (!startStatus.compareAndSet(false, true)) { - return; - } - consulClient = new ConsulClient(new ConsulRawClient(consulHost, Integer.parseInt(consulPort))); - - } - - @Override - public void shutdown() throws RegistryException { - if (!initStatus.compareAndSet(true, false)) { - return; - } - if (!startStatus.compareAndSet(true, false)) { - return; - } - consulClient = null; - } - - @Override - public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws RegistryException { - try { - String[] ipPort = eventMeshRegisterInfo.getEndPoint().split(IP_PORT_SEPARATOR); - if (ipPort == null || ipPort.length < 2) { - return false; - } - 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()); - } - log.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()); - } - log.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 void registerMetadata(Map metadataMap) { - - } -} 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 deleted file mode 100644 index d18efe974c..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-consul/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService +++ /dev/null @@ -1,16 +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. - -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 deleted file mode 100644 index 71ea739007..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-consul/src/test/java/ConsulRegistryServiceTest.java +++ /dev/null @@ -1,127 +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 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(); - ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.HTTP, configuration); - configuration.setNamesrvAddr("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("initStatus"); - initStatus.setAccessible(true); - Object initStatusField = initStatus.get(consulRegistryService); - - Field startStatus = consulRegistryServiceClass.getDeclaredField("startStatus"); - 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 deleted file mode 100644 index d94cf4ba27..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/build.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. - */ - -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" - - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' -} diff --git a/eventmesh-registry-plugin/eventmesh-registry-etcd/gradle.properties b/eventmesh-registry-plugin/eventmesh-registry-etcd/gradle.properties deleted file mode 100644 index 325b28af4a..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/gradle.properties +++ /dev/null @@ -1,19 +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. -# - -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/service/EtcdRegistryService.java b/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/service/EtcdRegistryService.java deleted file mode 100644 index c3cf5956af..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/java/org/apache/eventmesh/registry/etcd/service/EtcdRegistryService.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.Constants; -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.List; -import java.util.Map; -import java.util.Objects; -import java.util.Properties; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -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; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class EtcdRegistryService implements RegistryService { - - private final AtomicBoolean initStatus = new AtomicBoolean(false); - - private final AtomicBoolean startStatus = 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; - - @Getter - private Client etcdClient; - - private ConcurrentMap eventMeshRegisterInfoMap; - - private ScheduledExecutorService etcdRegistryMonitorExecutorService; - - @Override - public void init() throws RegistryException { - - if (!initStatus.compareAndSet(false, true)) { - return; - } - eventMeshRegisterInfoMap = new ConcurrentHashMap<>(ConfigurationContextUtil.KEYS.size()); - for (String key : ConfigurationContextUtil.KEYS) { - CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); - if (null == commonConfiguration) { - continue; - } - if (StringUtils.isBlank(commonConfiguration.getNamesrvAddr())) { - throw new RegistryException("namesrvAddr cannot be null"); - } - this.serverAddr = commonConfiguration.getNamesrvAddr(); - this.username = commonConfiguration.getEventMeshRegistryPluginUsername(); - this.password = commonConfiguration.getEventMeshRegistryPluginPassword(); - break; - } - etcdRegistryMonitorExecutorService = ThreadPoolFactory.createSingleScheduledExecutor( - "EtcdRegistryMonitorThread" - ); - } - - @Override - public void start() throws RegistryException { - - if (!startStatus.compareAndSet(false, true)) { - 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) { - log.error("[EtcdRegistryService][start] error", e); - throw new RegistryException(e.getMessage()); - } - } - - @Override - public void shutdown() throws RegistryException { - if (!initStatus.compareAndSet(true, false)) { - return; - } - if (!startStatus.compareAndSet(true, false)) { - return; - } - try { - if (etcdClient != null) { - etcdClient.close(); - } - if (etcdRegistryMonitorExecutorService != null && !etcdRegistryMonitorExecutorService.isShutdown()) { - etcdRegistryMonitorExecutorService.shutdown(); - } - } catch (Exception e) { - log.error("[EtcdRegistryService][shutdown] error", e); - throw new RegistryException(e.getMessage()); - } - log.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(Constants.DEFAULT_CHARSET)); - 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.parseObject(new String(kv.getValue().getBytes(), Constants.DEFAULT_CHARSET), EventMeshDataInfo.class); - eventMeshDataInfoList.add(eventMeshDataInfo); - } - } - } catch (Exception e) { - log.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) { - log.error("[EtcdRegistryService][findEventMeshInfoByCluster] error", e); - throw new RegistryException(e.getMessage()); - } - } - - @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(Objects.requireNonNull(JsonUtils.toJSONString(eventMeshDataInfo)) - .getBytes(Constants.DEFAULT_CHARSET)); - etcdClient.getKVClient().put(etcdKey, etcdValue, PutOption.newBuilder().withLeaseId(getLeaseId()).build()); - eventMeshRegisterInfoMap.put(eventMeshName, eventMeshRegisterInfo); - - log.info("EventMesh successfully registered to etcd, eventMeshClusterName: {}, eventMeshName: {}", - eventMeshClusterName, eventMeshName); - return true; - } catch (Exception e) { - log.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); - log.info("EventMesh successfully logout to etcd, eventMeshClusterName: {}, eventMeshName: {}", - eventMeshClusterName, eventMeshName); - return true; - } catch (Exception e) { - log.error("[EtcdRegistryService][unRegister] error, eventMeshClusterName: {}, eventMeshName: {}", - eventMeshClusterName, eventMeshName, e); - throw new RegistryException(e.getMessage()); - } - } - - 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(Constants.DEFAULT_CHARSET)); - } - - /** - * 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) { - log.error("get etcdKey[{}] failed", etcdKey, e); - } - if (CollectionUtils.isEmpty(keyValues)) { - log.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 deleted file mode 100644 index 56730d9290..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService +++ /dev/null @@ -1,16 +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. - -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 deleted file mode 100644 index afdf07026c..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-etcd/src/test/java/org/apache/eventmesh/registry/etcd/service/EtcdRegistryServiceTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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(); - configuration.setNamesrvAddr("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("initStatus"); - initStatus.setAccessible(true); - Object initStatusField = initStatus.get(etcdRegistryService); - - Field startStatus = etcdRegistryServiceClass.getDeclaredField("startStatus"); - 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 deleted file mode 100644 index 510b0daa3d..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-nacos/build.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. - */ - -dependencies { - implementation "com.alibaba.nacos:nacos-client" - implementation project(":eventmesh-registry-plugin:eventmesh-registry-api") - implementation project(":eventmesh-common") - testImplementation "org.mockito:mockito-core" - - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' -} diff --git a/eventmesh-registry-plugin/eventmesh-registry-nacos/gradle.properties b/eventmesh-registry-plugin/eventmesh-registry-nacos/gradle.properties deleted file mode 100644 index dc23fa1f66..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-nacos/gradle.properties +++ /dev/null @@ -1,19 +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. -# - -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/service/NacosRegistryService.java b/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/service/NacosRegistryService.java deleted file mode 100644 index fff040bf22..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/java/org/apache/eventmesh/registry/nacos/service/NacosRegistryService.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 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.List; -import java.util.Map; -import java.util.Objects; -import java.util.Properties; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; - -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; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class NacosRegistryService implements RegistryService { - - private final AtomicBoolean initStatus = new AtomicBoolean(false); - - private final AtomicBoolean startStatus = new AtomicBoolean(false); - - @Getter - private String serverAddr; - - @Getter - private String username; - - @Getter - private String password; - - @Getter - private NamingService namingService; - - private ConcurrentMap eventMeshRegisterInfoMap; - - @Override - public void init() throws RegistryException { - - if (!initStatus.compareAndSet(false, true)) { - return; - } - eventMeshRegisterInfoMap = new ConcurrentHashMap<>(ConfigurationContextUtil.KEYS.size()); - for (String key : ConfigurationContextUtil.KEYS) { - CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); - if (null == commonConfiguration) { - continue; - } - if (StringUtils.isBlank(commonConfiguration.getNamesrvAddr())) { - throw new RegistryException("namesrvAddr cannot be null"); - } - - this.serverAddr = commonConfiguration.getNamesrvAddr(); - this.username = commonConfiguration.getEventMeshRegistryPluginUsername(); - this.password = commonConfiguration.getEventMeshRegistryPluginPassword(); - break; - } - } - - @Override - public void start() throws RegistryException { - - if (!startStatus.compareAndSet(false, true)) { - 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) { - log.error("[NacosRegistryService][start] error", e); - throw new RegistryException(e.getMessage()); - } - } - - @Override - public void shutdown() throws RegistryException { - if (!initStatus.compareAndSet(true, false)) { - return; - } - if (!startStatus.compareAndSet(true, false)) { - return; - } - try { - namingService.shutDown(); - } catch (NacosException e) { - log.error("[NacosRegistryService][shutdown] error", e); - throw new RegistryException(e.getMessage()); - } - log.info("NacosRegistryService close"); - } - - @Override - public List findEventMeshInfoByCluster(String clusterName) throws RegistryException { - return findEventMeshInfos(true, Collections.singletonList(clusterName)); - } - - @Override - public List findAllEventMeshInfo() throws RegistryException { - return findEventMeshInfos(false, null); - } - - private List findEventMeshInfos(boolean inCluster, List clusters) { - List eventMeshDataInfoList = new ArrayList<>(); - for (String key : ConfigurationContextUtil.KEYS) { - CommonConfiguration configuration = ConfigurationContextUtil.get(key); - if (Objects.isNull(configuration)) { - continue; - } - String eventMeshName = configuration.getEventMeshName(); - try { - List instances = - namingService.selectInstances(eventMeshName + "-" + key, - key + "-" + (inCluster ? configuration.getEventMeshCluster() : NacosConstant.GROUP), - clusters, - 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) { - log.error("[NacosRegistryService][findEventMeshInfoByCluster] error", e); - throw new RegistryException(e.getMessage()); - } - } - return eventMeshDataInfoList; - } - - @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); - if (ipPort == null || ipPort.length < 2) { - return false; - } - 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) { - log.error("[NacosRegistryService][register] error", e); - throw new RegistryException(e.getMessage()); - } - log.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); - eventMeshRegisterInfoMap.remove(eventMeshName); - } catch (NacosException e) { - log.error("[NacosRegistryService][unRegister] error", e); - throw new RegistryException(e.getMessage()); - } - log.info("EventMesh successfully logout to nacos"); - return true; - } -} 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 deleted file mode 100644 index 3d28c7c18d..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-nacos/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService +++ /dev/null @@ -1,16 +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. - -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 deleted file mode 100644 index 6ebc78b203..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-nacos/src/test/java/org/apache/eventmesh/registry/nacos/service/NacosRegistryServiceTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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(); - configuration.setNamesrvAddr("127.0.0.1"); - configuration.setEventMeshRegistryPluginPassword("nacos"); - configuration.setEventMeshRegistryPluginUsername("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("initStatus"); - initStatus.setAccessible(true); - Object initStatusField = initStatus.get(nacosRegistryService); - - Field startStatus = nacosRegistryServiceClass.getDeclaredField("startStatus"); - 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); - } - -} diff --git a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/build.gradle b/eventmesh-registry-plugin/eventmesh-registry-zookeeper/build.gradle deleted file mode 100644 index 7e5c244a72..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/build.gradle +++ /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. - */ - -dependencies { - - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - - implementation 'org.apache.zookeeper:zookeeper' - implementation 'org.apache.curator:curator-client' - implementation 'org.apache.curator:curator-framework' - implementation 'org.apache.curator:curator-recipes' - - implementation project(":eventmesh-registry-plugin:eventmesh-registry-api") - implementation project(":eventmesh-common") - - testImplementation 'org.mockito:mockito-core' - testImplementation 'org.apache.curator:curator-test' -} diff --git a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/gradle.properties b/eventmesh-registry-plugin/eventmesh-registry-zookeeper/gradle.properties deleted file mode 100644 index 1743025814..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/gradle.properties +++ /dev/null @@ -1,18 +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. -# - -pluginType=registry -pluginName=zookeeper \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/java/org/apache/eventmesh/registry/zookeeper/service/ZookeeperRegistryService.java b/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/java/org/apache/eventmesh/registry/zookeeper/service/ZookeeperRegistryService.java deleted file mode 100644 index 2b7e322d21..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/java/org/apache/eventmesh/registry/zookeeper/service/ZookeeperRegistryService.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.registry.zookeeper.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.common.utils.JsonUtils; -import org.apache.eventmesh.registry.zookeeper.constant.ZookeeperConstant; -import org.apache.eventmesh.registry.zookeeper.pojo.EventMeshInstance; - -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.curator.RetryPolicy; -import org.apache.curator.framework.CuratorFramework; -import org.apache.curator.framework.CuratorFrameworkFactory; -import org.apache.curator.retry.ExponentialBackoffRetry; -import org.apache.zookeeper.CreateMode; -import org.apache.zookeeper.data.Stat; - -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.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ZookeeperRegistryService implements RegistryService { - - private final AtomicBoolean initStatus = new AtomicBoolean(false); - - private final AtomicBoolean startStatus = new AtomicBoolean(false); - - @Getter - private String serverAddr; - - @Getter - public CuratorFramework zkClient; - - private ConcurrentMap eventMeshRegisterInfoMap; - - @Override - public void init() throws RegistryException { - - if (!initStatus.compareAndSet(false, true)) { - log.warn("[ZookeeperRegistryService] has been init"); - return; - } - eventMeshRegisterInfoMap = new ConcurrentHashMap<>(ConfigurationContextUtil.KEYS.size()); - for (String key : ConfigurationContextUtil.KEYS) { - CommonConfiguration commonConfiguration = ConfigurationContextUtil.get(key); - if (null == commonConfiguration) { - continue; - } - if (StringUtils.isBlank(commonConfiguration.getNamesrvAddr())) { - throw new RegistryException("namesrvAddr cannot be null"); - } - this.serverAddr = commonConfiguration.getNamesrvAddr(); - break; - } - } - - @Override - public void start() throws RegistryException { - - if (!startStatus.compareAndSet(false, true)) { - log.warn("[ZookeeperRegistryService] has been start"); - return; - } - try { - RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5); - zkClient = CuratorFrameworkFactory.builder() - .connectString(serverAddr) - .retryPolicy(retryPolicy) - .namespace(ZookeeperConstant.NAMESPACE) - .build(); - zkClient.start(); - - } catch (Exception e) { - throw new RegistryException("ZookeeperRegistry starting failed", e); - } - } - - @Override - public void shutdown() throws RegistryException { - if (!initStatus.compareAndSet(true, false)) { - return; - } - if (!startStatus.compareAndSet(true, false)) { - return; - } - if (null != zkClient) { - zkClient.close(); - } - log.info("ZookeeperRegistryService closed"); - } - - @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.getEventMeshName(); - try { - String serviceName = eventMeshName.concat("-").concat(key); - String servicePath = formatServicePath(clusterName, serviceName); - - List instances = zkClient.getChildren() - .forPath(servicePath); - - if (CollectionUtils.isEmpty(instances)) { - continue; - } - - for (String endpoint : instances) { - String instancePath = servicePath.concat(ZookeeperConstant.PATH_SEPARATOR).concat(endpoint); - - Stat stat = new Stat(); - byte[] data; - try { - data = zkClient.getData() - .storingStatIn(stat) - .forPath(instancePath); - } catch (Exception e) { - log.warn("[ZookeeperRegistryService][findEventMeshInfoByCluster] failed for path: {}", instancePath, e); - continue; - } - - EventMeshInstance eventMeshInstance = JsonUtils.parseObject(new String(data, StandardCharsets.UTF_8), EventMeshInstance.class); - - EventMeshDataInfo eventMeshDataInfo = - new EventMeshDataInfo(clusterName, serviceName, endpoint, stat.getMtime(), - Objects.requireNonNull(eventMeshInstance, "instance must not be Null").getMetaData()); - - eventMeshDataInfoList.add(eventMeshDataInfo); - } - - } catch (Exception e) { - throw new RegistryException("ZookeeperRegistry findEventMeshInfoByCluster failed", e); - } - - } - return eventMeshDataInfoList; - } - - @Override - public List findAllEventMeshInfo() throws RegistryException { - List eventMeshDataInfoList = new ArrayList<>(); - - for (Map.Entry entry : eventMeshRegisterInfoMap.entrySet()) { - - String serviceName = entry.getKey(); - String clusterName = entry.getValue().getEventMeshClusterName(); - try { - String servicePath = formatServicePath(clusterName, serviceName); - - List instances = zkClient.getChildren() - .forPath(servicePath); - - if (CollectionUtils.isEmpty(instances)) { - continue; - } - - for (String endpoint : instances) { - String instancePath = servicePath.concat(ZookeeperConstant.PATH_SEPARATOR).concat(endpoint); - - Stat stat = new Stat(); - byte[] data; - try { - data = zkClient.getData() - .storingStatIn(stat) - .forPath(instancePath); - } catch (Exception e) { - log.warn("[ZookeeperRegistryService][findAllEventMeshInfo] failed for path: {}", instancePath, e); - continue; - } - - EventMeshInstance eventMeshInstance = JsonUtils.parseObject(new String(data, StandardCharsets.UTF_8), EventMeshInstance.class); - - EventMeshDataInfo eventMeshDataInfo = - new EventMeshDataInfo(clusterName, serviceName, endpoint, stat.getMtime(), - Objects.requireNonNull(eventMeshInstance, "instance must not be Null").getMetaData()); - - eventMeshDataInfoList.add(eventMeshDataInfo); - } - - } catch (Exception e) { - throw new RegistryException("ZookeeperRegistry findAllEventMeshInfo failed", e); - } - } - return eventMeshDataInfoList; - } - - @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(ZookeeperConstant.IP_PORT_SEPARATOR); - if (null == ipPort || ipPort.length < 2) { - return false; - } - String ip = ipPort[0]; - int port = Integer.parseInt(ipPort[1]); - String eventMeshName = eventMeshRegisterInfo.getEventMeshName(); - String eventMeshClusterName = eventMeshRegisterInfo.getEventMeshClusterName(); - Map> instanceNumMap = eventMeshRegisterInfo.getEventMeshInstanceNumMap(); - Map metadata = eventMeshRegisterInfo.getMetadata(); - - EventMeshInstance eventMeshInstance = new EventMeshInstance(); - eventMeshInstance.setIp(ip); - eventMeshInstance.setPort(port); - eventMeshInstance.setInstanceNumMap(instanceNumMap); - eventMeshInstance.setMetaData(metadata); - - // clusterName/eventMeshName/ip:port - final String path = formatInstancePath(eventMeshClusterName, eventMeshName, eventMeshRegisterInfo.getEndPoint()); - - zkClient.create() - .orSetData() - .creatingParentsIfNeeded() - .withMode(CreateMode.EPHEMERAL) - .forPath(path, - Objects.requireNonNull(JsonUtils.toJSONString(eventMeshInstance), "instance must not be Null").getBytes(StandardCharsets.UTF_8)); - - eventMeshRegisterInfoMap.put(eventMeshName, eventMeshRegisterInfo); - } catch (Exception e) { - throw new RegistryException("ZookeeperRegistry register failed", e); - } - log.info("EventMesh successfully registered to zookeeper"); - return true; - } - - - @Override - public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws RegistryException { - try { - String eventMeshName = eventMeshUnRegisterInfo.getEventMeshName(); - String eventMeshClusterName = eventMeshUnRegisterInfo.getEventMeshClusterName(); - - String path = formatInstancePath(eventMeshClusterName, eventMeshName, eventMeshUnRegisterInfo.getEndPoint()); - - zkClient.delete().forPath(path); - } catch (Exception e) { - throw new RegistryException("ZookeeperRegistry unRegister failed", e); - } - log.info("EventMesh successfully logout to zookeeper"); - return true; - } - - private String formatInstancePath(String clusterName, String serviceName, String endPoint) { - return ZookeeperConstant.PATH_SEPARATOR.concat(clusterName) - .concat(ZookeeperConstant.PATH_SEPARATOR).concat(serviceName) - .concat(ZookeeperConstant.PATH_SEPARATOR).concat(endPoint); - } - - private String formatServicePath(String clusterName, String serviceName) { - return ZookeeperConstant.PATH_SEPARATOR.concat(clusterName) - .concat(ZookeeperConstant.PATH_SEPARATOR).concat(serviceName); - } -} diff --git a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService b/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService deleted file mode 100644 index 82909f46a9..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.registry.RegistryService +++ /dev/null @@ -1,16 +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. - -zookeeper=org.apache.eventmesh.registry.zookeeper.service.ZookeeperRegistryService \ No newline at end of file diff --git a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/test/java/org/apache/eventmesh/registry/zookeeper/service/ZookeeperRegistryServiceTest.java b/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/test/java/org/apache/eventmesh/registry/zookeeper/service/ZookeeperRegistryServiceTest.java deleted file mode 100644 index 9e5782648f..0000000000 --- a/eventmesh-registry-plugin/eventmesh-registry-zookeeper/src/test/java/org/apache/eventmesh/registry/zookeeper/service/ZookeeperRegistryServiceTest.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.registry.zookeeper.service; - -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.curator.test.TestingServer; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -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; - -import com.google.common.collect.Maps; - -@RunWith(MockitoJUnitRunner.class) -public class ZookeeperRegistryServiceTest { - - @Mock - private EventMeshRegisterInfo eventMeshRegisterInfo; - @Mock - private EventMeshUnRegisterInfo eventMeshUnRegisterInfo; - - private ZookeeperRegistryService zkRegistryService; - - private TestingServer testingServer; - - @Before - public void setUp() throws Exception { - testingServer = new TestingServer(1500, true); - testingServer.start(); - - zkRegistryService = new ZookeeperRegistryService(); - CommonConfiguration configuration = new CommonConfiguration(); - configuration.setNamesrvAddr("127.0.0.1:1500"); - configuration.setEventMeshName("eventmesh"); - ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.HTTP, configuration); - - Mockito.when(eventMeshRegisterInfo.getEventMeshClusterName()).thenReturn("eventmeshCluster"); - Mockito.when(eventMeshRegisterInfo.getEventMeshName()).thenReturn("eventmesh-" + ConfigurationContextUtil.HTTP); - Mockito.when(eventMeshRegisterInfo.getEndPoint()).thenReturn("127.0.0.1:8848"); - Mockito.when(eventMeshRegisterInfo.getEventMeshInstanceNumMap()).thenReturn(Maps.newHashMap()); - HashMap metaData = Maps.newHashMap(); - metaData.put("test", "a"); - Mockito.when(eventMeshRegisterInfo.getMetadata()).thenReturn(metaData); - - Mockito.when(eventMeshUnRegisterInfo.getEventMeshClusterName()).thenReturn("eventmeshCluster"); - Mockito.when(eventMeshUnRegisterInfo.getEventMeshName()).thenReturn("eventmesh-" + ConfigurationContextUtil.HTTP); - Mockito.when(eventMeshUnRegisterInfo.getEndPoint()).thenReturn("127.0.0.1:8848"); - } - - @After - public void after() throws Exception { - zkRegistryService.shutdown(); - testingServer.close(); - } - - @Test - public void testInit() { - zkRegistryService.init(); - zkRegistryService.start(); - Assert.assertNotNull(zkRegistryService.getServerAddr()); - } - - @Test - public void testStart() { - zkRegistryService.init(); - zkRegistryService.start(); - Assert.assertNotNull(zkRegistryService.getZkClient()); - } - - @Test - public void testShutdown() throws NoSuchFieldException, IllegalAccessException { - zkRegistryService.init(); - zkRegistryService.start(); - zkRegistryService.shutdown(); - - Class zkRegistryServiceClass = ZookeeperRegistryService.class; - Field initStatus = zkRegistryServiceClass.getDeclaredField("initStatus"); - initStatus.setAccessible(true); - Object initStatusField = initStatus.get(zkRegistryService); - - Field startStatus = zkRegistryServiceClass.getDeclaredField("startStatus"); - startStatus.setAccessible(true); - Object startStatusField = startStatus.get(zkRegistryService); - - Assert.assertFalse((Boolean.parseBoolean(initStatusField.toString()))); - Assert.assertFalse((Boolean.parseBoolean(startStatusField.toString()))); - } - - - @Test - public void testFindEventMeshInfoByCluster() { - zkRegistryService.init(); - zkRegistryService.start(); - zkRegistryService.register(eventMeshRegisterInfo); - - final List result = zkRegistryService.findEventMeshInfoByCluster(eventMeshRegisterInfo.getEventMeshClusterName()); - - Assert.assertNotNull(result); - } - - @Test - public void testFindAllEventMeshInfo() { - zkRegistryService.init(); - zkRegistryService.start(); - zkRegistryService.register(eventMeshRegisterInfo); - - List result = zkRegistryService.findAllEventMeshInfo(); - - Assert.assertNotNull(result); - } - - @Test - public void testRegisterMetadata() { - zkRegistryService.init(); - zkRegistryService.start(); - zkRegistryService.register(eventMeshRegisterInfo); - Map metaData = Maps.newConcurrentMap(); - metaData.put("test", "a"); - zkRegistryService.registerMetadata(metaData); - List infoList = - zkRegistryService.findEventMeshInfoByCluster(eventMeshRegisterInfo.getEventMeshClusterName()); - - Assert.assertNotNull(infoList); - } - - @Test() - public void testRegister() { - zkRegistryService.init(); - zkRegistryService.start(); - zkRegistryService.register(eventMeshRegisterInfo); - } - - @Test() - public void testUnRegister() { - zkRegistryService.init(); - zkRegistryService.start(); - boolean register = zkRegistryService.register(eventMeshRegisterInfo); - - Assert.assertTrue(register); - - boolean unRegister = zkRegistryService.unRegister(eventMeshUnRegisterInfo); - - Assert.assertTrue(unRegister); - } -} diff --git a/eventmesh-retry/eventmesh-retry-api/build.gradle b/eventmesh-retry/eventmesh-retry-api/build.gradle new file mode 100644 index 0000000000..228d23f595 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-api/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 { + implementation project(":eventmesh-storage-plugin:eventmesh-storage-api") + implementation project(":eventmesh-common") + implementation project(":eventmesh-spi") + + implementation 'io.cloudevents:cloudevents-core' + implementation 'io.cloudevents:cloudevents-json-jackson' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation 'org.junit.jupiter:junit-jupiter' +} \ No newline at end of file diff --git a/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/AbstractRetryer.java b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/AbstractRetryer.java new file mode 100644 index 0000000000..0b6ddf844b --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/AbstractRetryer.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.retry.api; + +import org.apache.eventmesh.common.EventMeshThreadFactory; +import org.apache.eventmesh.retry.api.timer.HashedWheelTimer; +import org.apache.eventmesh.retry.api.timer.Timer; +import org.apache.eventmesh.retry.api.timer.TimerTask; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractRetryer implements Retryer { + + private volatile Timer timer; + + private static final int MAX_PENDING_TIMEOUTS = 10000; + + @Override + public void newTimeout(TimerTask timerTask, long delay, TimeUnit timeUnit) { + log.debug("[HASHED-WHEEL-TIMER] executed! taskClass={}, nowTime={}", + timeUnit.getClass().getName(), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); + timer.newTimeout(timerTask, delay, timeUnit); + } + + @Override + public void start() { + if (timer == null) { + synchronized (this) { + if (timer == null) { + timer = new HashedWheelTimer( + new EventMeshThreadFactory("failback-cluster-timer", true), + 1, + TimeUnit.SECONDS, 512, MAX_PENDING_TIMEOUTS); + } + } + } + log.info("EventMesh retryer started......"); + } + + @Override + public void shutdown() { + timer.stop(); + log.info("EventMesh retryer shutdown......"); + } + + @Override + public long getPendingTimeouts() { + if (timer == null) { + return 0; + } + return timer.pendingTimeouts(); + } + + @Override + public void printState() { + if (timer == null) { + log.warn("No HashedWheelTimer is provided!"); + return; + } + HashedWheelTimer hashedWheelTimer = (HashedWheelTimer) timer; + + log.info("[Retry-HashedWheelTimer] state=================="); + log.info("Running :{}", !hashedWheelTimer.isStop()); + log.info("Pending Timeouts: {} | Cancelled Timeouts: {}", hashedWheelTimer.pendingTimeouts(), hashedWheelTimer.cancelledTimeouts()); + log.info("========================================"); + } +} diff --git a/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/Retryer.java b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/Retryer.java new file mode 100644 index 0000000000..82634e1739 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/Retryer.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.retry.api; + +import org.apache.eventmesh.retry.api.timer.TimerTask; + +import java.util.concurrent.TimeUnit; + +/** + * Retryer interface. + */ +public interface Retryer { + + void start(); + + void shutdown(); + + long getPendingTimeouts(); + + void printState(); + + void newTimeout(TimerTask timerTask, long delay, TimeUnit timeUnit); + +} diff --git a/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/conf/RetryConfiguration.java b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/conf/RetryConfiguration.java new file mode 100644 index 0000000000..351a06fd39 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/conf/RetryConfiguration.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.retry.api.conf; + +import org.apache.eventmesh.api.producer.Producer; +import org.apache.eventmesh.common.protocol.SubscriptionMode; + +import io.cloudevents.CloudEvent; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class RetryConfiguration { + + private CloudEvent event; + + private String consumerGroupName; + + private Producer producer; + + private String topic; + + private SubscriptionMode subscriptionMode; +} diff --git a/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/strategy/RetryStrategy.java b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/strategy/RetryStrategy.java new file mode 100644 index 0000000000..739be171b8 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/strategy/RetryStrategy.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.retry.api.strategy; + +import org.apache.eventmesh.retry.api.conf.RetryConfiguration; +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +/** + * Retry strategy. + */ +@EventMeshSPI(isSingleton = false, eventMeshExtensionType = EventMeshExtensionType.RETRY) +public interface RetryStrategy { + + void retry(RetryConfiguration configuration); +} diff --git a/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/HashedWheelTimer.java b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/HashedWheelTimer.java new file mode 100644 index 0000000000..6dd21233bb --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/HashedWheelTimer.java @@ -0,0 +1,798 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.retry.api.timer; + +import static org.apache.eventmesh.common.Constants.OS_NAME_KEY; +import static org.apache.eventmesh.common.Constants.OS_WIN_PREFIX; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Locale; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A {@link Timer} optimized for approximated I/O timeout scheduling. + * + *

Tick Duration

+ *

+ * As described with 'approximated', this timer does not execute the scheduled + * {@link TimerTask} on time. {@link HashedWheelTimer}, on every tick, will + * check if there are any {@link TimerTask}s behind the schedule and execute + * them. + *

+ * You can increase or decrease the accuracy of the execution timing by + * specifying smaller or larger tick duration in the constructor. In most + * network applications, I/O timeout does not need to be accurate. Therefore, + * the default tick duration is 100 milliseconds, and you will not need to try + * different configurations in most cases. + * + *

Ticks per Wheel (Wheel Size)

+ *

+ * {@link HashedWheelTimer} maintains a data structure called 'wheel'. + * To put simply, a wheel is a hash table of {@link TimerTask}s whose hash + * function is 'deadline of the task'. The default number of ticks per wheel + * (i.e. the size of the wheel) is 512. You could specify a larger value + * if you are going to schedule a lot of timeouts. + * + *

Do not create many instances.

+ *

+ * {@link HashedWheelTimer} creates a new thread whenever it is instantiated and + * started. Therefore, you should make sure to create only one instance and + * share it across your application. One of the common mistakes, that makes + * your application unresponsive, is to create a new instance for every connection. + * + *

Implementation Details

+ *

+ * {@link HashedWheelTimer} is based on + * George Varghese and + * Tony Lauck's paper, + * 'Hashed + * and Hierarchical Timing Wheels: data structures to efficiently implement a + * timer facility'. More comprehensive slides are located + * here. + */ +public class HashedWheelTimer implements Timer { + + private static final Logger logger = LoggerFactory.getLogger(HashedWheelTimer.class); + + private static final AtomicInteger INSTANCE_COUNTER = new AtomicInteger(); + private static final AtomicBoolean WARNED_TOO_MANY_INSTANCES = new AtomicBoolean(); + private static final int INSTANCE_COUNT_LIMIT = 64; + private static final AtomicIntegerFieldUpdater WORKER_STATE_UPDATER = + AtomicIntegerFieldUpdater.newUpdater(HashedWheelTimer.class, "workerState"); + + private final Worker worker = new Worker(); + private final Thread workerThread; + + private static final int WORKER_STATE_INIT = 0; + private static final int WORKER_STATE_STARTED = 1; + private static final int WORKER_STATE_SHUTDOWN = 2; + + /** + * 0 - init, 1 - started, 2 - shut down + */ + @SuppressWarnings({"unused", "FieldMayBeFinal"}) + private volatile int workerState; + + private final long tickDuration; + private final HashedWheelBucket[] wheel; + private final int mask; + private final CountDownLatch startTimeInitialized = new CountDownLatch(1); + private final Queue timeouts = new LinkedBlockingQueue<>(); + private final Queue cancelledTimeouts = new LinkedBlockingQueue<>(); + private final AtomicLong pendingTimeouts = new AtomicLong(0); + private final long maxPendingTimeouts; + + private volatile long startTime; + + /** + * Creates a new timer with the default thread factory + * ({@link Executors#defaultThreadFactory()}), default tick duration, and + * default number of ticks per wheel. + */ + public HashedWheelTimer() { + this(Executors.defaultThreadFactory()); + } + + /** + * Creates a new timer with the default thread factory + * ({@link Executors#defaultThreadFactory()}) and default number of ticks + * per wheel. + * + * @param tickDuration the duration between tick + * @param unit the time unit of the {@code tickDuration} + * @throws NullPointerException if {@code unit} is {@code null} + * @throws IllegalArgumentException if {@code tickDuration} is <= 0 + */ + public HashedWheelTimer(long tickDuration, TimeUnit unit) { + this(Executors.defaultThreadFactory(), tickDuration, unit); + } + + /** + * Creates a new timer with the default thread factory + * ({@link Executors#defaultThreadFactory()}). + * + * @param tickDuration the duration between tick + * @param unit the time unit of the {@code tickDuration} + * @param ticksPerWheel the size of the wheel + * @throws NullPointerException if {@code unit} is {@code null} + * @throws IllegalArgumentException if either of {@code tickDuration} and {@code ticksPerWheel} is <= 0 + */ + public HashedWheelTimer(long tickDuration, TimeUnit unit, int ticksPerWheel) { + this(Executors.defaultThreadFactory(), tickDuration, unit, ticksPerWheel); + } + + /** + * Creates a new timer with the default tick duration and default number of + * ticks per wheel. + * + * @param threadFactory a {@link ThreadFactory} that creates a + * background {@link Thread} which is dedicated to + * {@link TimerTask} execution. + * @throws NullPointerException if {@code threadFactory} is {@code null} + */ + public HashedWheelTimer(ThreadFactory threadFactory) { + this(threadFactory, 100, TimeUnit.MILLISECONDS); + } + + /** + * Creates a new timer with the default number of ticks per wheel. + * + * @param threadFactory a {@link ThreadFactory} that creates a + * background {@link Thread} which is dedicated to + * {@link TimerTask} execution. + * @param tickDuration the duration between tick + * @param unit the time unit of the {@code tickDuration} + * @throws NullPointerException if either of {@code threadFactory} and {@code unit} is {@code null} + * @throws IllegalArgumentException if {@code tickDuration} is <= 0 + */ + public HashedWheelTimer( + ThreadFactory threadFactory, long tickDuration, TimeUnit unit) { + this(threadFactory, tickDuration, unit, 512); + } + + /** + * Creates a new timer. + * + * @param threadFactory a {@link ThreadFactory} that creates a + * background {@link Thread} which is dedicated to + * {@link TimerTask} execution. + * @param tickDuration the duration between tick + * @param unit the time unit of the {@code tickDuration} + * @param ticksPerWheel the size of the wheel + * @throws NullPointerException if either of {@code threadFactory} and {@code unit} is {@code null} + * @throws IllegalArgumentException if either of {@code tickDuration} and {@code ticksPerWheel} is <= 0 + */ + public HashedWheelTimer( + ThreadFactory threadFactory, + long tickDuration, TimeUnit unit, int ticksPerWheel) { + this(threadFactory, tickDuration, unit, ticksPerWheel, -1); + } + + /** + * Creates a new timer. + * + * @param threadFactory a {@link ThreadFactory} that creates a + * background {@link Thread} which is dedicated to + * {@link TimerTask} execution. + * @param tickDuration the duration between tick + * @param unit the time unit of the {@code tickDuration} + * @param ticksPerWheel the size of the wheel + * @param maxPendingTimeouts The maximum number of pending timeouts after which call to + * {@code newTimeout} will result in + * {@link RejectedExecutionException} + * being thrown. No maximum pending timeouts limit is assumed if + * this value is 0 or negative. + * @throws NullPointerException if either of {@code threadFactory} and {@code unit} is {@code null} + * @throws IllegalArgumentException if either of {@code tickDuration} and {@code ticksPerWheel} is <= 0 + */ + public HashedWheelTimer( + ThreadFactory threadFactory, + long tickDuration, TimeUnit unit, int ticksPerWheel, + long maxPendingTimeouts) { + + if (threadFactory == null) { + throw new NullPointerException("threadFactory"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + if (tickDuration <= 0) { + throw new IllegalArgumentException("tickDuration must be greater than 0: " + tickDuration); + } + if (ticksPerWheel <= 0) { + throw new IllegalArgumentException("ticksPerWheel must be greater than 0: " + ticksPerWheel); + } + + // Normalize ticksPerWheel to power of two and initialize the wheel. + wheel = createWheel(ticksPerWheel); + mask = wheel.length - 1; + + // Convert tickDuration to nanos. + this.tickDuration = unit.toNanos(tickDuration); + + // Prevent overflow. + if (this.tickDuration >= Long.MAX_VALUE / wheel.length) { + throw new IllegalArgumentException(String.format( + "tickDuration: %d (expected: 0 < tickDuration in nanos < %d", + tickDuration, Long.MAX_VALUE / wheel.length)); + } + workerThread = threadFactory.newThread(worker); + + this.maxPendingTimeouts = maxPendingTimeouts; + + if (INSTANCE_COUNTER.incrementAndGet() > INSTANCE_COUNT_LIMIT && WARNED_TOO_MANY_INSTANCES.compareAndSet(false, true)) { + reportTooManyInstances(); + } + } + + private static HashedWheelBucket[] createWheel(int ticksPerWheel) { + if (ticksPerWheel <= 0) { + throw new IllegalArgumentException( + "ticksPerWheel must be greater than 0: " + ticksPerWheel); + } + if (ticksPerWheel > 1073741824) { + throw new IllegalArgumentException( + "ticksPerWheel may not be greater than 2^30: " + ticksPerWheel); + } + + ticksPerWheel = normalizeTicksPerWheel(ticksPerWheel); + HashedWheelBucket[] wheel = new HashedWheelBucket[ticksPerWheel]; + for (int i = 0; i < wheel.length; i++) { + wheel[i] = new HashedWheelBucket(); + } + return wheel; + } + + private static int normalizeTicksPerWheel(int ticksPerWheel) { + int normalizedTicksPerWheel = ticksPerWheel - 1; + normalizedTicksPerWheel |= normalizedTicksPerWheel >>> 1; + normalizedTicksPerWheel |= normalizedTicksPerWheel >>> 2; + normalizedTicksPerWheel |= normalizedTicksPerWheel >>> 4; + normalizedTicksPerWheel |= normalizedTicksPerWheel >>> 8; + normalizedTicksPerWheel |= normalizedTicksPerWheel >>> 16; + return normalizedTicksPerWheel + 1; + } + + /** + * Starts the background thread explicitly. The background thread will + * start automatically on demand even if you did not call this method. + * + * @throws IllegalStateException if this timer has been + * {@linkplain #stop() stopped} already + */ + public void start() { + switch (WORKER_STATE_UPDATER.get(this)) { + case WORKER_STATE_INIT: + if (WORKER_STATE_UPDATER.compareAndSet(this, WORKER_STATE_INIT, WORKER_STATE_STARTED)) { + workerThread.start(); + } + break; + case WORKER_STATE_STARTED: + break; + case WORKER_STATE_SHUTDOWN: + throw new IllegalStateException("cannot be started once stopped"); + default: + throw new Error("Invalid WorkerState"); + } + + // Wait until the startTime is initialized by the worker. + while (startTime == 0) { + try { + startTimeInitialized.await(); + } catch (InterruptedException ignore) { + // Ignore - it will be ready very soon. + } + } + } + + @Override + public Set stop() { + if (Thread.currentThread() == workerThread) { + throw new IllegalStateException( + HashedWheelTimer.class.getSimpleName() + ".stop() cannot be called from " + TimerTask.class.getSimpleName()); + } + + if (!WORKER_STATE_UPDATER.compareAndSet(this, WORKER_STATE_STARTED, WORKER_STATE_SHUTDOWN)) { + // workerState can be 0 or 2 at this moment - let it always be 2. + if (WORKER_STATE_UPDATER.getAndSet(this, WORKER_STATE_SHUTDOWN) != WORKER_STATE_SHUTDOWN) { + INSTANCE_COUNTER.decrementAndGet(); + } + + return Collections.emptySet(); + } + + try { + boolean interrupted = false; + while (workerThread.isAlive()) { + workerThread.interrupt(); + try { + workerThread.join(100); + } catch (InterruptedException ignored) { + interrupted = true; + } + } + + if (interrupted) { + Thread.currentThread().interrupt(); + } + } finally { + INSTANCE_COUNTER.decrementAndGet(); + } + return worker.unprocessedTimeouts(); + } + + @Override + public boolean isStop() { + return WORKER_STATE_SHUTDOWN == WORKER_STATE_UPDATER.get(this); + } + + @Override + public Timeout newTimeout(TimerTask task, long delay, TimeUnit unit) { + if (task == null) { + throw new NullPointerException("task"); + } + if (unit == null) { + throw new NullPointerException("unit"); + } + + long pendingTimeoutsCount = pendingTimeouts.incrementAndGet(); + + if (maxPendingTimeouts > 0 && pendingTimeoutsCount > maxPendingTimeouts) { + pendingTimeouts.decrementAndGet(); + throw new RejectedExecutionException("Number of pending timeouts (" + + pendingTimeoutsCount + ") is greater than or equal to maximum allowed pending " + + "timeouts (" + maxPendingTimeouts + ")"); + } + + start(); + + // Add the timeout to the timeout queue which will be processed on the next tick. + // During processing all the queued HashedWheelTimeouts will be added to the correct HashedWheelBucket. + long deadline = System.nanoTime() + unit.toNanos(delay) - startTime; + + // Guard against overflow. + if (delay > 0 && deadline < 0) { + deadline = Long.MAX_VALUE; + } + HashedWheelTimeout timeout = new HashedWheelTimeout(this, task, deadline); + timeouts.add(timeout); + return timeout; + } + + /** + * Returns the number of pending timeouts of this {@link Timer}. + */ + public long pendingTimeouts() { + return pendingTimeouts.get(); + } + + /** + * Returns the number of cancelled timeouts of this {@link Timer}. + */ + public long cancelledTimeouts() { + return cancelledTimeouts.size(); + } + + private static void reportTooManyInstances() { + logger.error("You are creating too many HashedWheelTimer instances. is a shared resource that must be reused across the JVM, " + + "so that only a few instances are created."); + } + + private final class Worker implements Runnable { + + private final Set unprocessedTimeouts = new HashSet(); + + private long tick; + + @Override + public void run() { + // Initialize the startTime. + startTime = System.nanoTime(); + if (startTime == 0) { + // We use 0 as an indicator for the uninitialized value here, so make sure it's not 0 when initialized. + startTime = 1; + } + + // Notify the other threads waiting for the initialization at start(). + startTimeInitialized.countDown(); + + do { + final long deadline = waitForNextTick(); + if (deadline > 0) { + int idx = (int) (tick & mask); + processCancelledTasks(); + HashedWheelBucket bucket = + wheel[idx]; + transferTimeoutsToBuckets(); + bucket.expireTimeouts(deadline); + tick++; + } + } while (WORKER_STATE_UPDATER.get(HashedWheelTimer.this) == WORKER_STATE_STARTED); + + // Fill the unprocessedTimeouts so we can return them from stop() method. + for (HashedWheelBucket bucket : wheel) { + bucket.clearTimeouts(unprocessedTimeouts); + } + for (;;) { + HashedWheelTimeout timeout = timeouts.poll(); + if (timeout == null) { + break; + } + if (!timeout.isCancelled()) { + unprocessedTimeouts.add(timeout); + } + } + processCancelledTasks(); + } + + private void transferTimeoutsToBuckets() { + // transfer only max. 100000 timeouts per tick to prevent a thread to stale the workerThread when it just + // adds new timeouts in a loop. + for (int i = 0; i < 100000; i++) { + HashedWheelTimeout timeout = timeouts.poll(); + if (timeout == null) { + // all processed + break; + } + if (timeout.state() == HashedWheelTimeout.ST_CANCELLED) { + // Was cancelled in the meantime. + continue; + } + + long calculated = timeout.deadline / tickDuration; + timeout.remainingRounds = (calculated - tick) / wheel.length; + + // Ensure we don't schedule for past. + final long ticks = Math.max(calculated, tick); + int stopIndex = (int) (ticks & mask); + + HashedWheelBucket bucket = wheel[stopIndex]; + bucket.addTimeout(timeout); + } + } + + private void processCancelledTasks() { + for (;;) { + HashedWheelTimeout timeout = cancelledTimeouts.poll(); + if (timeout == null) { + // all processed + break; + } + try { + timeout.remove(); + } catch (Throwable t) { + logger.warn("An exception was thrown while process a cancellation task", t); + } + } + } + + /** + * calculate goal nanoTime from startTime and current tick number, + * then wait until that goal has been reached. + * + * @return Long.MIN_VALUE if received a shutdown request, + * current time otherwise (with Long.MIN_VALUE changed by +1) + */ + private long waitForNextTick() { + long deadline = tickDuration * (tick + 1); + + for (;;) { + final long currentTime = System.nanoTime() - startTime; + long sleepTimeMs = (deadline - currentTime + 999999) / 1000000; + + if (sleepTimeMs <= 0) { + if (currentTime == Long.MIN_VALUE) { + return -Long.MAX_VALUE; + } else { + return currentTime; + } + } + if (isWindows()) { + sleepTimeMs = sleepTimeMs / 10 * 10; + } + + try { + Thread.sleep(sleepTimeMs); + } catch (InterruptedException ignored) { + if (WORKER_STATE_UPDATER.get(HashedWheelTimer.this) == WORKER_STATE_SHUTDOWN) { + return Long.MIN_VALUE; + } + } + } + } + + Set unprocessedTimeouts() { + return Collections.unmodifiableSet(unprocessedTimeouts); + } + } + + private static final class HashedWheelTimeout implements Timeout { + + private static final int ST_INIT = 0; + private static final int ST_CANCELLED = 1; + private static final int ST_EXPIRED = 2; + private static final AtomicIntegerFieldUpdater STATE_UPDATER = + AtomicIntegerFieldUpdater.newUpdater(HashedWheelTimeout.class, "state"); + + private final HashedWheelTimer timer; + private final TimerTask task; + private final long deadline; + + private volatile int state = ST_INIT; + + /** + * RemainingRounds will be calculated and set by Worker.transferTimeoutsToBuckets() before the + * HashedWheelTimeout will be added to the correct HashedWheelBucket. + */ + long remainingRounds; + + /** + * This will be used to chain timeouts in HashedWheelTimerBucket via a double-linked-list. + * As only the workerThread will act on it there is no need for synchronization / volatile. + */ + HashedWheelTimeout next; + HashedWheelTimeout prev; + + /** + * The bucket to which the timeout was added + */ + HashedWheelBucket bucket; + + HashedWheelTimeout(HashedWheelTimer timer, TimerTask task, long deadline) { + this.timer = timer; + this.task = task; + this.deadline = deadline; + } + + @Override + public Timer timer() { + return timer; + } + + @Override + public TimerTask task() { + return task; + } + + @Override + public boolean cancel() { + // only update the state it will be removed from HashedWheelBucket on next tick. + if (!compareAndSetState(ST_INIT, ST_CANCELLED)) { + return false; + } + // If a task should be canceled we put this to another queue which will be processed on each tick. + // So this means that we will have a GC latency of max. 1 tick duration which is good enough. This way we + // can make again use of our LinkedBlockingQueue and so minimize the locking / overhead as much as possible. + timer.cancelledTimeouts.add(this); + return true; + } + + void remove() { + HashedWheelBucket bucket = this.bucket; + if (bucket != null) { + bucket.remove(this); + } else { + timer.pendingTimeouts.decrementAndGet(); + } + } + + public boolean compareAndSetState(int expected, int state) { + return STATE_UPDATER.compareAndSet(this, expected, state); + } + + public int state() { + return state; + } + + @Override + public boolean isCancelled() { + return state() == ST_CANCELLED; + } + + @Override + public boolean isExpired() { + return state() == ST_EXPIRED; + } + + public void expire() { + if (!compareAndSetState(ST_INIT, ST_EXPIRED)) { + return; + } + + try { + task.run(); + task.setExecuteTimeHook(System.currentTimeMillis()); + } catch (Throwable t) { + logger.warn("An exception was thrown by " + TimerTask.class.getSimpleName() + '.', t); + } + } + + @Override + public String toString() { + final long currentTime = System.nanoTime(); + long remaining = deadline - currentTime + timer.startTime; + String simpleClassName = getClass().getSimpleName(); + + StringBuilder buf = new StringBuilder(192) + .append(simpleClassName) + .append('(') + .append("deadline: "); + if (remaining > 0) { + buf.append(remaining) + .append(" ns later"); + } else if (remaining < 0) { + buf.append(-remaining) + .append(" ns ago"); + } else { + buf.append("now"); + } + + if (isCancelled()) { + buf.append(", cancelled"); + } + + return buf.append(", task: ") + .append(task()) + .append(')') + .toString(); + } + } + + /** + * Bucket that stores HashedWheelTimeouts. These are stored in a linked-list like datastructure to allow easy + * removal of HashedWheelTimeouts in the middle. Also the HashedWheelTimeout act as nodes themself and so no + * extra object creation is needed. + */ + private static final class HashedWheelBucket { + + /** + * Used for the linked-list datastructure + */ + private HashedWheelTimeout head; + private HashedWheelTimeout tail; + + /** + * Add {@link HashedWheelTimeout} to this bucket. + */ + void addTimeout(HashedWheelTimeout timeout) { + assert timeout.bucket == null; + timeout.bucket = this; + if (head == null) { + head = tail = timeout; + } else { + tail.next = timeout; + timeout.prev = tail; + tail = timeout; + } + } + + /** + * Expire all {@link HashedWheelTimeout}s for the given {@code deadline}. + */ + void expireTimeouts(long deadline) { + HashedWheelTimeout timeout = head; + + // process all timeouts + while (timeout != null) { + HashedWheelTimeout next = timeout.next; + if (timeout.remainingRounds <= 0) { + next = remove(timeout); + if (timeout.deadline <= deadline) { + timeout.expire(); + } else { + // The timeout was placed into a wrong slot. This should never happen. + throw new IllegalStateException(String.format( + "timeout.deadline (%d) > deadline (%d)", timeout.deadline, deadline)); + } + } else if (timeout.isCancelled()) { + next = remove(timeout); + } else { + timeout.remainingRounds--; + } + timeout = next; + } + } + + public HashedWheelTimeout remove(HashedWheelTimeout timeout) { + HashedWheelTimeout next = timeout.next; + // remove timeout that was either processed or cancelled by updating the linked-list + if (timeout.prev != null) { + timeout.prev.next = next; + } + if (timeout.next != null) { + timeout.next.prev = timeout.prev; + } + + if (timeout == head) { + // if timeout is also the tail we need to adjust the entry too + if (timeout == tail) { + tail = null; + head = null; + } else { + head = next; + } + } else if (timeout == tail) { + // if the timeout is the tail modify the tail to be the prev node. + tail = timeout.prev; + } + // null out prev, next and bucket to allow for GC. + timeout.prev = null; + timeout.next = null; + timeout.bucket = null; + timeout.timer.pendingTimeouts.decrementAndGet(); + return next; + } + + /** + * Clear this bucket and return all not expired / cancelled {@link Timeout}s. + */ + void clearTimeouts(Set set) { + for (;;) { + HashedWheelTimeout timeout = pollTimeout(); + if (timeout == null) { + return; + } + if (timeout.isExpired() || timeout.isCancelled()) { + continue; + } + set.add(timeout); + } + } + + private HashedWheelTimeout pollTimeout() { + HashedWheelTimeout head = this.head; + if (head == null) { + return null; + } + HashedWheelTimeout next = head.next; + if (next == null) { + tail = this.head = null; + } else { + this.head = next; + next.prev = null; + } + + // null out prev and next to allow for GC. + head.next = null; + head.prev = null; + head.bucket = null; + return head; + } + } + + private static final boolean IS_OS_WINDOWS = System.getProperty(OS_NAME_KEY, "").toLowerCase(Locale.US).contains(OS_WIN_PREFIX); + + private boolean isWindows() { + return IS_OS_WINDOWS; + } +} diff --git a/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/Timeout.java b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/Timeout.java new file mode 100644 index 0000000000..e6485ff511 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/Timeout.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.retry.api.timer; + +/** + * A handle associated with a {@link TimerTask} that is returned by a + * {@link Timer}. + */ +public interface Timeout { + + /** + * Returns the {@link Timer} that created this handle. + */ + Timer timer(); + + /** + * Returns the {@link TimerTask} which is associated with this handle. + */ + TimerTask task(); + + /** + * Returns {@code true} if and only if the {@link TimerTask} associated + * with this handle has been expired. + */ + boolean isExpired(); + + /** + * Returns {@code true} if and only if the {@link TimerTask} associated + * with this handle has been cancelled. + */ + boolean isCancelled(); + + /** + * Attempts to cancel the {@link TimerTask} associated with this handle. + * If the task has been executed or cancelled already, it will return with + * no side effect. + * + * @return True if the cancellation completed successfully, otherwise false + */ + boolean cancel(); +} diff --git a/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/Timer.java b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/Timer.java new file mode 100644 index 0000000000..50d1ce06a8 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/Timer.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.retry.api.timer; + +import java.util.Set; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; + +/** + * Schedules {@link TimerTask}s for one-time future execution in a background + * thread. + */ +public interface Timer { + + /** + * Schedules the specified {@link TimerTask} for one-time execution after + * the specified delay. + * + * @return a handle which is associated with the specified task + * @throws IllegalStateException if this timer has been {@linkplain #stop() stopped} already + * @throws RejectedExecutionException if the pending timeouts are too many and creating new timeout + * can cause instability in the system. + */ + Timeout newTimeout(TimerTask task, long delay, TimeUnit unit); + + /** + * Releases all resources acquired by this {@link Timer} and cancels all + * tasks which were scheduled but not executed yet. + * + * @return the handles associated with the tasks which were canceled by + * this method + */ + Set stop(); + + /** + * the timer is stop + * + * @return true for stop + */ + boolean isStop(); + + /** + * the pending timeouts + * @return count of pending timeout + */ + long pendingTimeouts(); +} diff --git a/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/TimerTask.java b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/TimerTask.java new file mode 100644 index 0000000000..879481454e --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-api/src/main/java/org/apache/eventmesh/retry/api/timer/TimerTask.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.retry.api.timer; + +import java.util.concurrent.TimeUnit; + +/** + * A task which is executed after the delay specified with + * {@link Timer#newTimeout(TimerTask, long, TimeUnit)} (TimerTask, long, TimeUnit)}. + */ +public interface TimerTask { + + /** + * Executed after the delay specified with + * {@link Timer#newTimeout(TimerTask, long, TimeUnit)}. + */ + void run() throws Exception; + + /** + * Hook method to set the execute time. + * @param executeTime execute time + */ + void setExecuteTimeHook(long executeTime); +} diff --git a/eventmesh-retry/eventmesh-retry-rocketmq/build.gradle b/eventmesh-retry/eventmesh-retry-rocketmq/build.gradle new file mode 100644 index 0000000000..3d33929b44 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-rocketmq/build.gradle @@ -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. + */ + +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-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-storage-plugin:eventmesh-storage-api") + implementation project(":eventmesh-storage-plugin:eventmesh-storage-rocketmq") + implementation rocketmq + implementation project(":eventmesh-retry:eventmesh-retry-api") + implementation project(":eventmesh-common") + + implementation 'io.cloudevents:cloudevents-core' + implementation 'io.cloudevents:cloudevents-json-jackson' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + testImplementation 'org.junit.jupiter:junit-jupiter' +} \ No newline at end of file diff --git a/eventmesh-retry/eventmesh-retry-rocketmq/gradle.properties b/eventmesh-retry/eventmesh-retry-rocketmq/gradle.properties new file mode 100644 index 0000000000..5114e05231 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-rocketmq/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. +# + +rocketmq_version=4.9.5 +pluginType=retry +pluginName=rocketmq \ No newline at end of file diff --git a/eventmesh-retry/eventmesh-retry-rocketmq/src/main/java/org/apache/eventmesh/retry/rocketmq/RocketMQRetryStrategyImpl.java b/eventmesh-retry/eventmesh-retry-rocketmq/src/main/java/org/apache/eventmesh/retry/rocketmq/RocketMQRetryStrategyImpl.java new file mode 100644 index 0000000000..9d817eec50 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-rocketmq/src/main/java/org/apache/eventmesh/retry/rocketmq/RocketMQRetryStrategyImpl.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.retry.rocketmq; + +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.api.producer.Producer; +import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; +import org.apache.eventmesh.retry.api.conf.RetryConfiguration; +import org.apache.eventmesh.retry.api.strategy.RetryStrategy; + +import org.apache.rocketmq.common.MixAll; + +import java.util.Objects; + +import io.cloudevents.CloudEvent; +import io.cloudevents.core.builder.CloudEventBuilder; + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RocketMQRetryStrategyImpl implements RetryStrategy { + + @Override + public void retry(RetryConfiguration configuration) { + sendMessageBack(configuration); + } + + @SneakyThrows + private void sendMessageBack(final RetryConfiguration configuration) { + CloudEvent event = configuration.getEvent(); + String topic = configuration.getTopic(); + String consumerGroupName = configuration.getConsumerGroupName(); + String retryTopicName = MixAll.getRetryTopic(consumerGroupName); + + String bizSeqNo = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.BIZSEQNO.getKey())).toString(); + String uniqueId = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.UNIQUEID.getKey())).toString(); + CloudEvent retryEvent = CloudEventBuilder.from(event) + .withExtension(ProtocolKey.TOPIC, topic) + .withSubject(retryTopicName) + .build(); + Producer producer = configuration.getProducer(); + producer.publish(retryEvent, new SendCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + log.info("consumer:{} consume success,, bizSeqno:{}, uniqueId:{}", + consumerGroupName, bizSeqNo, uniqueId); + } + + @Override + public void onException(OnExceptionContext context) { + log.warn("consumer:{} consume fail, sendMessageBack, bizSeqno:{}, uniqueId:{}", + consumerGroupName, bizSeqNo, uniqueId, context.getException()); + } + }); + } +} diff --git a/eventmesh-retry/eventmesh-retry-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.retry.api.strategy.RetryStrategy b/eventmesh-retry/eventmesh-retry-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.retry.api.strategy.RetryStrategy new file mode 100644 index 0000000000..71c2006e92 --- /dev/null +++ b/eventmesh-retry/eventmesh-retry-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.retry.api.strategy.RetryStrategy @@ -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.retry.rocketmq.RocketMQRetryStrategyImpl \ No newline at end of file diff --git a/eventmesh-runtime/bin/start.sh b/eventmesh-runtime/bin/start.sh index 3ad63a71ea..96fac20989 100644 --- a/eventmesh-runtime/bin/start.sh +++ b/eventmesh-runtime/bin/start.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # # Licensed to Apache Software Foundation (ASF) under one or more contributor # license agreements. See the NOTICE file distributed with @@ -21,24 +21,30 @@ # Java Environment Setting #=========================================================================================== set -e -#Server configuration may be inconsistent, add these configurations to avoid garbled code problems +# 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" +TMP_JAVA_HOME="/customize/your/java/home/here" -#detect operating system. +# Detect operating system. OS=$(uname) -function is_java8 { +function is_java8_or_11 { 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 + [[ "$("$_java" -version 2>&1)" =~ 'java version "1.8' || "$("$_java" -version 2>&1)" =~ 'openjdk version "1.8' || "$("$_java" -version 2>&1)" =~ 'java version "11' || "$("$_java" -version 2>&1)" =~ 'openjdk version "11' ]] || return 2 return 0 } -#0(not running), 1(is running) +function extract_java_version { + local _java="$1" + local version=$("$_java" -version 2>&1 | awk -F '"' '/version/ {print $2}' | awk -F '.' '{if ($1 == 1 && $2 == 8) print "8"; else if ($1 == 11) print "11"; else print "unknown"}') + echo "$version" +} + +# 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` @@ -53,6 +59,13 @@ function get_pid { local ppid="" if [ -f ${EVENTMESH_HOME}/bin/pid.file ]; then ppid=$(cat ${EVENTMESH_HOME}/bin/pid.file) + # If the process does not exist, it indicates that the previous process terminated abnormally. + if [ ! -d /proc/$ppid ]; then + # Remove the residual file. + rm ${EVENTMESH_HOME}/bin/pid.file + echo -e "ERROR\t EventMesh process had already terminated unexpectedly before, please check log output." + ppid="" + fi else if [[ $OS =~ Msys ]]; then # There is a Bug on Msys that may not be able to kill the identified process @@ -61,40 +74,45 @@ function get_pid { # 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'}) + if [ $DOCKER ]; then + # No need to exclude root user in Docker containers. + ppid=$(ps -C java -o user,pid,command --cols 99999 | grep -w $EVENTMESH_HOME | grep -i "org.apache.eventmesh.runtime.boot.EventMeshStartup" | 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 fi echo "$ppid"; } +#=========================================================================================== +# Locate Java Executable +#=========================================================================================== -if [[ -d "$TMP_JAVA_HOME" ]] && is_java8 "$TMP_JAVA_HOME/bin/java"; then +if [[ -d "$TMP_JAVA_HOME" ]] && is_java8_or_11 "$TMP_JAVA_HOME/bin/java"; then JAVA="$TMP_JAVA_HOME/bin/java" -elif [[ -d "$JAVA_HOME" ]] && is_java8 "$JAVA_HOME/bin/java"; then + JAVA_VERSION=$(extract_java_version "$TMP_JAVA_HOME/bin/java") +elif [[ -d "$JAVA_HOME" ]] && is_java8_or_11 "$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_VERSION=$(extract_java_version "$JAVA_HOME/bin/java") +elif is_java8_or_11 "$(which java)"; then JAVA="$(which java)" + JAVA_VERSION=$(extract_java_version "$(which java)") else - echo -e "ERROR\t java(1.8) not found, operation abort." + echo -e "ERROR\t Java 8 or 11 not found, operation abort." exit 9; fi -echo "eventmesh use java location= "$JAVA - -EVENTMESH_HOME=`cd $(dirname $0)/.. && pwd` +echo "EventMesh using Java version: $JAVA_VERSION, path: $JAVA" +EVENTMESH_HOME=$(cd "$(dirname "$0")/.." && pwd) export EVENTMESH_HOME -export EVENTMESH_LOG_HOME=${EVENTMESH_HOME}/logs +EVENTMESH_LOG_HOME="${EVENTMESH_HOME}/logs" +export EVENTMESH_LOG_HOME -echo "EVENTMESH_HOME : ${EVENTMESH_HOME}, EVENTMESH_LOG_HOME : ${EVENTMESH_LOG_HOME}" +echo -e "EVENTMESH_HOME : ${EVENTMESH_HOME}\nEVENTMESH_LOG_HOME : ${EVENTMESH_LOG_HOME}" function make_logs_dir { if [ ! -e "${EVENTMESH_LOG_HOME}" ]; then mkdir -p "${EVENTMESH_LOG_HOME}"; fi @@ -102,7 +120,7 @@ function make_logs_dir { error_exit () { - echo "ERROR: $1 !!" + echo -e "ERROR\t $1 !!" exit 1 } @@ -116,12 +134,23 @@ export JAVA_HOME #elif [ $1 = "dev" ]; then JAVA_OPT="${JAVA_OPT} -server -Xms128M -Xmx256M -Xmn128m -XX:SurvivorRatio=4" #fi +GC_LOG_FILE="${EVENTMESH_LOG_HOME}/eventmesh_gc_%p.log" + #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} -verbose:gc" +if [[ "$JAVA_VERSION" == "8" ]]; then + # Set JAVA_OPT for Java 8 + JAVA_OPT="${JAVA_OPT} -Xloggc:${GC_LOG_FILE} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" + JAVA_OPT="${JAVA_OPT} -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy" +elif [[ "$JAVA_VERSION" == "11" ]]; then + # Set JAVA_OPT for Java 11 + XLOG_PARAM="time,level,tags:filecount=5,filesize=30m" + JAVA_OPT="${JAVA_OPT} -Xlog:gc*:${GC_LOG_FILE}:${XLOG_PARAM}" + JAVA_OPT="${JAVA_OPT} -Xlog:safepoint:${GC_LOG_FILE}:${XLOG_PARAM} -Xlog:ergo*=debug:${GC_LOG_FILE}:${XLOG_PARAM}" +fi +JAVA_OPT="${JAVA_OPT} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${EVENTMESH_LOG_HOME} -XX:ErrorFile=${EVENTMESH_LOG_HOME}/hs_err_%p.log" JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=8G" @@ -148,22 +177,24 @@ JAVA_OPT="${JAVA_OPT} -DeventMeshPluginDir=${EVENTMESH_HOME}/plugin" #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; +if [[ $pid == "ERROR"* ]]; then + echo -e "${pid}" + exit 9 +fi +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 - +echo "Using Java version: $JAVA_VERSION, path: $JAVA" >> ${EVENTMESH_LOG_HOME}/eventmesh.out EVENTMESH_MAIN=org.apache.eventmesh.runtime.boot.EventMeshStartup -if [ $DOCKER ] -then +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 +echo $!>${EVENTMESH_HOME}/bin/pid.file fi exit 0 diff --git a/eventmesh-runtime/bin/stop.sh b/eventmesh-runtime/bin/stop.sh index e85fbf5ec1..b4f1d00154 100644 --- a/eventmesh-runtime/bin/stop.sh +++ b/eventmesh-runtime/bin/stop.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # # Licensed to Apache Software Foundation (ASF) under one or more contributor # license agreements. See the NOTICE file distributed with @@ -17,7 +17,7 @@ # specific language governing permissions and limitations # under the License. -#detect operating system. +# Detect operating system OS=$(uname) EVENTMESH_HOME=`cd $(dirname $0)/.. && pwd` @@ -28,6 +28,13 @@ function get_pid { local ppid="" if [ -f ${EVENTMESH_HOME}/bin/pid.file ]; then ppid=$(cat ${EVENTMESH_HOME}/bin/pid.file) + # If the process does not exist, it indicates that the previous process terminated abnormally. + if [ ! -d /proc/$ppid ]; then + # Remove the residual file and return an error status. + rm ${EVENTMESH_HOME}/bin/pid.file + echo -e "ERROR\t EventMesh process had already terminated unexpectedly before, please check log output." + ppid="" + fi else if [[ $OS =~ Msys ]]; then # There is a Bug on Msys that may not be able to kill the identified process @@ -44,20 +51,24 @@ function get_pid { } pid=$(get_pid) +if [[ $pid == "ERROR"* ]]; then + echo -e "${pid}" + exit 9 +fi if [ -z "$pid" ];then - echo -e "No eventmesh running.." - exit 0; + echo -e "ERROR\t No EventMesh server running." + exit 9 fi kill ${pid} -echo "Send shutdown request to eventmesh(${pid}) OK" +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 ..." + echo "[$no] server shutting down ..." sleep 1 continue fi diff --git a/eventmesh-runtime/build.gradle b/eventmesh-runtime/build.gradle index b5bf575338..eef0bb2f92 100644 --- a/eventmesh-runtime/build.gradle +++ b/eventmesh-runtime/build.gradle @@ -15,8 +15,6 @@ * limitations under the License. */ -def grpcVersion = '1.43.2' - dependencies { implementation 'io.cloudevents:cloudevents-core' implementation 'io.cloudevents:cloudevents-json-jackson' @@ -35,29 +33,28 @@ dependencies { implementation "commons-io:commons-io" + implementation "commons-validator:commons-validator" + implementation project(":eventmesh-common") + implementation project(":eventmesh-filter") implementation project(":eventmesh-spi") implementation project(":eventmesh-storage-plugin:eventmesh-storage-api") implementation project(":eventmesh-storage-plugin:eventmesh-storage-standalone") + implementation project(":eventmesh-storage-plugin:eventmesh-storage-rocketmq") 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-security-plugin:eventmesh-security-auth-token") - - 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-transformer") + implementation project(":eventmesh-meta:eventmesh-meta-api") + implementation project(":eventmesh-meta:eventmesh-meta-nacos") 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}" + implementation "io.grpc:grpc-core" + implementation "io.grpc:grpc-protobuf" + implementation "io.grpc:grpc-stub" + implementation "io.grpc:grpc-netty" + implementation "io.grpc:grpc-netty-shaded" compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' @@ -79,10 +76,10 @@ dependencies { implementation project(":eventmesh-webhook:eventmesh-webhook-api") implementation project(":eventmesh-webhook:eventmesh-webhook-receive") - testImplementation "org.mockito:mockito-core" + implementation project(":eventmesh-retry:eventmesh-retry-api") + testImplementation "org.mockito:mockito-inline" - testImplementation "org.powermock:powermock-module-junit4" - testImplementation "org.powermock:powermock-api-mockito2" + testImplementation "org.mockito:mockito-junit-jupiter" testImplementation "commons-io:commons-io" testCompileOnly 'org.projectlombok:lombok' diff --git a/eventmesh-runtime/conf/eventmesh.properties b/eventmesh-runtime/conf/eventmesh.properties index 4473c5cbd2..cabe3f9bc5 100644 --- a/eventmesh-runtime/conf/eventmesh.properties +++ b/eventmesh-runtime/conf/eventmesh.properties @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -###############################EVNETMESH-runtime ENV################################# +########################## EventMesh Runtime Environment ########################## eventMesh.server.idc=DEFAULT eventMesh.server.env=PRD eventMesh.server.provide.protocols=HTTP,TCP,GRPC @@ -23,9 +23,9 @@ eventMesh.server.name=EVENTMESH-runtime eventMesh.sysid=0000 eventMesh.server.http.port=10105 eventMesh.server.grpc.port=10205 -########################## eventMesh tcp configuration ############################ +########################## EventMesh TCP Configuration ########################## eventMesh.server.tcp.enabled=true -eventMesh.server.tcp.port=10002 +eventMesh.server.tcp.port=10000 eventMesh.server.tcp.readerIdleSeconds=120 eventMesh.server.tcp.writerIdleSeconds=120 eventMesh.server.tcp.allIdleSeconds=120 @@ -49,46 +49,81 @@ eventMesh.server.maxEventBatchSize=10 # thread number about global scheduler eventMesh.server.global.scheduler=5 eventMesh.server.tcp.taskHandleExecutorPoolSize=8 -#retry +# 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.retry.plugin.type=default + +# runtime admin eventMesh.server.admin.http.port=10106 -#registry -eventMesh.server.registry.registerIntervalInMills=10000 -eventMesh.server.registry.fetchRegistryAddrIntervalInMills=20000 -#auto-ack +# metaStorage +eventMesh.server.metaStorage.metaStorageIntervalInMills=10000 +eventMesh.server.metaStorage.fetchMetaStorageAddrIntervalInMills=20000 +# auto-ack #eventMesh.server.defibus.client.comsumeTimeoutInMin=5 -#sleep interval between closing client of different group in server graceful shutdown +# 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 +# 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 +# connector plugin eventMesh.connector.plugin.type=standalone -#storage plugin +# storage plugin eventMesh.storage.plugin.type=standalone -#security plugin +# security plugin eventMesh.server.security.enabled=false eventMesh.security.plugin.type=security eventMesh.security.validation.type.token=false eventMesh.security.publickey= -#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 +# metaStorage plugin +eventMesh.metaStorage.plugin.enabled=false +eventMesh.metaStorage.plugin.type=nacos +eventMesh.metaStorage.plugin.server-addr=127.0.0.1:8848 +eventMesh.metaStorage.plugin.username=nacos +eventMesh.metaStorage.plugin.password=nacos +# metaStorage plugin: nacos +#eventMesh.metaStorage.nacos.endpoint= +#eventMesh.metaStorage.nacos.accessKey= +#eventMesh.metaStorage.nacos.secretKey= +#eventMesh.metaStorage.nacos.clusterName= +#eventMesh.metaStorage.nacos.namespace= +# The default value is half of CPU's num +#eventMesh.metaStorage.nacos.namingPollingThreadCount=5 + +# metaStorage plugin: zookeeper +#eventMesh.metaStorage.zookeeper.scheme= +#eventMesh.metaStorage.zookeeper.auth= +#eventMesh.metaStorage.zookeeper.connectionTimeoutMs= +#eventMesh.metaStorage.zookeeper.sessionTimeoutMs= + +# Fully qualified name of org.apache.curator.RetryPolicy implementation +#eventMesh.metaStorage.zookeeper.retryPolicy.class= + +# Constructor arguments for different org.apache.curator.RetryPolicy implementations +#eventMesh.metaStorage.zookeeper.retryPolicy.baseSleepTimeMs= +#eventMesh.metaStorage.zookeeper.retryPolicy.maxRetries= +#eventMesh.metaStorage.zookeeper.retryPolicy.maxSleepTimeMs= +#eventMesh.metaStorage.zookeeper.retryPolicy.retryIntervalMs= +#eventMesh.metaStorage.zookeeper.retryPolicy.nTimes= +#eventMesh.metaStorage.zookeeper.retryPolicy.sleepMsBetweenRetries= + +# The TLS configuration of metaStorage plugin: consul +# keyStoreInstanceType's value can refer to com.ecwid.consul.transport.TLSConfig.KeyStoreInstanceType +#eventMesh.metaStorage.consul.tls.keyStoreInstanceType= +#eventMesh.metaStorage.consul.tls.certificatePath= +#eventMesh.metaStorage.consul.tls.certificatePassword= +#eventMesh.metaStorage.consul.tls.keyStorePath= +#eventMesh.metaStorage.consul.tls.keyStorePassword= # metrics plugin, if you have multiple plugin, you can use ',' to split eventMesh.metrics.plugin=prometheus @@ -100,12 +135,12 @@ 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 +# 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 +# Webhook CloudEvent sending mode. This property is the same as the eventMesh.storage.plugin.type configuration. eventMesh.webHook.producer.storage=standalone diff --git a/eventmesh-runtime/conf/log4j2.xml b/eventmesh-runtime/conf/log4j2.xml index 756abeac33..3ce5ac985e 100644 --- a/eventmesh-runtime/conf/log4j2.xml +++ b/eventmesh-runtime/conf/log4j2.xml @@ -60,7 +60,7 @@ - + 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 index c2adcce873..94061e5027 100644 --- 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 @@ -20,8 +20,8 @@ import org.apache.eventmesh.api.acl.AclProperties; import org.apache.eventmesh.api.acl.AclService; import org.apache.eventmesh.api.exception.AclException; -import org.apache.eventmesh.api.registry.bo.EventMeshAppSubTopicInfo; -import org.apache.eventmesh.api.registry.bo.EventMeshServicePubTopicInfo; +import org.apache.eventmesh.api.meta.bo.EventMeshAppSubTopicInfo; +import org.apache.eventmesh.api.meta.bo.EventMeshServicePubTopicInfo; import org.apache.eventmesh.common.protocol.tcp.UserAgent; import org.apache.eventmesh.spi.EventMeshExtensionFactory; @@ -35,6 +35,7 @@ @Slf4j public class Acl { + private static final Map ACL_CACHE = new HashMap<>(16); private AclService aclService; @@ -196,6 +197,7 @@ private static AclProperties buildTcpAclProperties(String remoteAddr, UserAgent aclProperties.setPwd(userAgent.getPassword()); aclProperties.setSubsystem(userAgent.getSubsystem()); aclProperties.setRequestCode(requestCode); + aclProperties.setVersion(userAgent.getVersion()); if (StringUtils.isNotBlank(topic)) { aclProperties.setTopic(topic); } 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 index 1614fddfa8..bf0c132a0e 100644 --- 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 @@ -17,13 +17,13 @@ package org.apache.eventmesh.runtime.admin.controller; -import org.apache.eventmesh.admin.rocketmq.controller.AdminController; import org.apache.eventmesh.runtime.admin.handler.ConfigurationHandler; import org.apache.eventmesh.runtime.admin.handler.DeleteWebHookConfigHandler; import org.apache.eventmesh.runtime.admin.handler.EventHandler; import org.apache.eventmesh.runtime.admin.handler.GrpcClientHandler; import org.apache.eventmesh.runtime.admin.handler.HTTPClientHandler; import org.apache.eventmesh.runtime.admin.handler.InsertWebHookConfigHandler; +import org.apache.eventmesh.runtime.admin.handler.MetaHandler; import org.apache.eventmesh.runtime.admin.handler.MetricsHandler; import org.apache.eventmesh.runtime.admin.handler.QueryRecommendEventMeshHandler; import org.apache.eventmesh.runtime.admin.handler.QueryWebHookConfigByIdHandler; @@ -31,7 +31,6 @@ 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.RegistryHandler; import org.apache.eventmesh.runtime.admin.handler.RejectAllClientHandler; import org.apache.eventmesh.runtime.admin.handler.RejectClientByIpPortHandler; import org.apache.eventmesh.runtime.admin.handler.RejectClientBySubSystemHandler; @@ -44,7 +43,7 @@ import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; -import org.apache.eventmesh.runtime.registry.Registry; +import org.apache.eventmesh.runtime.meta.MetaStorage; import org.apache.eventmesh.webhook.admin.AdminWebHookConfigOperationManager; import org.apache.eventmesh.webhook.api.WebHookConfigOperation; @@ -52,12 +51,18 @@ import java.net.InetSocketAddress; import java.util.Objects; - import com.sun.net.httpserver.HttpServer; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +/** + * This class is responsible for managing the client connections + * and initializing the client handlers. + *

+ * It starts the AdminController for managing the event store or MQ. + */ + @SuppressWarnings("restriction") @Slf4j public class ClientManageController { @@ -68,36 +73,50 @@ public class ClientManageController { private final transient EventMeshGrpcServer eventMeshGrpcServer; - private final transient Registry eventMeshRegistry; + private final transient MetaStorage eventMeshMetaStorage; @Setter private AdminWebHookConfigOperationManager adminWebHookConfigOperationManage; + /** + * Constructs a new ClientManageController with the given server instance. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param eventMeshHTTPServer the HTTP server instance of EventMesh + * @param eventMeshGrpcServer the gRPC server instance of EventMesh + * @param eventMeshMetaStorage the registry adaptor of EventMesh + */ public ClientManageController(EventMeshTCPServer eventMeshTCPServer, EventMeshHTTPServer eventMeshHTTPServer, EventMeshGrpcServer eventMeshGrpcServer, - Registry eventMeshRegistry) { + MetaStorage eventMeshMetaStorage) { this.eventMeshTCPServer = eventMeshTCPServer; this.eventMeshHTTPServer = eventMeshHTTPServer; this.eventMeshGrpcServer = eventMeshGrpcServer; - this.eventMeshRegistry = eventMeshRegistry; - + this.eventMeshMetaStorage = eventMeshMetaStorage; } - + /** + * Invoke this method to start this controller on the specified port. + * + * @throws IOException if an I/O error occurs while starting the server + */ public void start() throws IOException { + // Get the server's admin port. int port = eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshServerAdminPort(); + // Create an HTTP server and bind it to the specified port. HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); HttpHandlerManager httpHandlerManager = new HttpHandlerManager(); - //todo Optimized for automatic injection + // TODO: Optimized for automatic injection + + // Initialize the client handler and register it with the HTTP handler manager. initClientHandler(eventMeshTCPServer, eventMeshHTTPServer, - eventMeshGrpcServer, eventMeshRegistry, httpHandlerManager); + eventMeshGrpcServer, eventMeshMetaStorage, httpHandlerManager); + // Register the handlers from the HTTP handler manager with the HTTP server. httpHandlerManager.registerHttpHandler(server); - AdminController adminController = new AdminController(); - adminController.run(server); server.start(); log.info("ClientManageController start success, port:{}", port); @@ -106,7 +125,7 @@ public void start() throws IOException { private void initClientHandler(EventMeshTCPServer eventMeshTCPServer, EventMeshHTTPServer eventMeshHTTPServer, EventMeshGrpcServer eventMeshGrpcServer, - Registry eventMeshRegistry, + MetaStorage eventMeshMetaStorage, HttpHandlerManager httpHandlerManager) { new ShowClientHandler(eventMeshTCPServer, httpHandlerManager); new ShowClientBySystemHandler(eventMeshTCPServer, httpHandlerManager); @@ -128,7 +147,7 @@ private void initClientHandler(EventMeshTCPServer eventMeshTCPServer, new MetricsHandler(eventMeshHTTPServer, eventMeshTCPServer, httpHandlerManager); new TopicHandler(eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshStoragePluginType(), httpHandlerManager); new EventHandler(eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshStoragePluginType(), httpHandlerManager); - new RegistryHandler(eventMeshRegistry, httpHandlerManager); + new MetaHandler(eventMeshMetaStorage, httpHandlerManager); if (Objects.nonNull(adminWebHookConfigOperationManage.getWebHookConfigOperation())) { WebHookConfigOperation webHookConfigOperation = adminWebHookConfigOperationManage.getWebHookConfigOperation(); @@ -140,5 +159,4 @@ private void initClientHandler(EventMeshTCPServer eventMeshTCPServer, } } - } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/controller/HttpHandlerManager.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/controller/HttpHandlerManager.java index 032b03581f..47557608f1 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/controller/HttpHandlerManager.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/controller/HttpHandlerManager.java @@ -26,16 +26,35 @@ import com.sun.net.httpserver.HttpServer; /** - * httpHandlerManager + * This class manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@linkplain com.sun.net.httpserver.HttpServer HttpServer}. */ + public class HttpHandlerManager { private final List httpHandlers = new ArrayList<>(); + /** + * Registers an HTTP handler. + * + * @param httpHandler The {@link HttpHandler} to be registered. + * A handler which is invoked to process HTTP exchanges. + * Each HTTP exchange is handled by one of these handlers. + */ public void register(HttpHandler httpHandler) { this.httpHandlers.add(httpHandler); } + /** + * Registers multiple HTTP handlers to a given HttpServer. + *

+ * Each HTTP handler is annotated with the {@link EventHttpHandler} annotation, + * which specifies the path where the handler should be registered. + * + * @param server A HttpServer object that is bound to an IP address and port number + * and listens for incoming TCP connections from clients on this address. + * The registered HTTP handlers will be associated with this server. + */ public void registerHttpHandler(HttpServer server) { httpHandlers.forEach(httpHandler -> { EventHttpHandler eventHttpHandler = httpHandler.getClass().getAnnotation(EventHttpHandler.class); diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AbstractHttpHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AbstractHttpHandler.java index cfcb85d03c..e13ce6d771 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AbstractHttpHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/AbstractHttpHandler.java @@ -24,8 +24,12 @@ import lombok.Data; /** - * AbstractHttpHandler + * An abstract class that implements the {@link HttpHandler} interface + * and provides basic functionality for HTTP request handling. + *

+ * Subclasses should extend this class to implement specific HTTP request handling logic. */ + @Data public abstract class AbstractHttpHandler implements HttpHandler { diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ConfigurationHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ConfigurationHandler.java index 3232273ece..3b0982a907 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ConfigurationHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/ConfigurationHandler.java @@ -35,14 +35,20 @@ import java.io.StringWriter; import java.util.Objects; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * The config handler + * This class handles the {@code /configuration} endpoint, + * corresponding to the {@code eventmesh-dashboard} path {@code /}. + *

+ * This handler is responsible for retrieving the current configuration information of the EventMesh node, + * including service name, service environment, and listening ports for various protocols. + * + * @see AbstractHttpHandler */ + @Slf4j @EventHttpHandler(path = "/configuration") public class ConfigurationHandler extends AbstractHttpHandler { @@ -51,12 +57,20 @@ public class ConfigurationHandler extends AbstractHttpHandler { private final EventMeshHTTPConfiguration eventMeshHTTPConfiguration; private final EventMeshGrpcConfiguration eventMeshGrpcConfiguration; + /** + * Constructs a new instance with the provided configurations and HTTP handler manager. + * + * @param eventMeshTCPConfiguration the TCP configuration for EventMesh + * @param eventMeshHTTPConfiguration the HTTP configuration for EventMesh + * @param eventMeshGrpcConfiguration the gRPC configuration for EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public ConfigurationHandler( EventMeshTCPConfiguration eventMeshTCPConfiguration, EventMeshHTTPConfiguration eventMeshHTTPConfiguration, EventMeshGrpcConfiguration eventMeshGrpcConfiguration, - HttpHandlerManager httpHandlerManager - ) { + HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPConfiguration = eventMeshTCPConfiguration; this.eventMeshHTTPConfiguration = eventMeshHTTPConfiguration; @@ -64,7 +78,13 @@ public ConfigurationHandler( } /** - * OPTIONS /configuration + * Handles the OPTIONS request first for {@code /configuration}. + *

+ * This method adds CORS (Cross-Origin Resource Sharing) response headers to + * the {@link HttpExchange} object and sends a 200 status code. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void preflight(HttpExchange httpExchange) throws IOException { httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); @@ -77,7 +97,12 @@ void preflight(HttpExchange httpExchange) throws IOException { } /** - * GET /config Return a response that contains the EventMesh configuration + * Handles the GET request for {@code /configuration}. + *

+ * This method retrieves the EventMesh configuration information and returns it as a JSON response. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void get(HttpExchange httpExchange) throws IOException { httpExchange.getResponseHeaders().add(EventMeshConstants.CONTENT_TYPE, EventMeshConstants.APPLICATION_JSON); @@ -86,7 +111,7 @@ void get(HttpExchange httpExchange) throws IOException { try { GetConfigurationResponse getConfigurationResponse = new GetConfigurationResponse( eventMeshTCPConfiguration.getSysID(), - eventMeshTCPConfiguration.getNamesrvAddr(), + eventMeshTCPConfiguration.getMetaStorageAddr(), eventMeshTCPConfiguration.getEventMeshEnv(), eventMeshTCPConfiguration.getEventMeshIDC(), eventMeshTCPConfiguration.getEventMeshCluster(), @@ -94,7 +119,7 @@ void get(HttpExchange httpExchange) throws IOException { eventMeshTCPConfiguration.getEventMeshName(), eventMeshTCPConfiguration.getEventMeshWebhookOrigin(), eventMeshTCPConfiguration.isEventMeshServerSecurityEnable(), - eventMeshTCPConfiguration.isEventMeshServerRegistryEnable(), + eventMeshTCPConfiguration.isEventMeshServerMetaStorageEnable(), // TCP Configuration eventMeshTCPConfiguration.getEventMeshTcpServerPort(), // HTTP Configuration @@ -102,8 +127,7 @@ void get(HttpExchange httpExchange) throws IOException { eventMeshHTTPConfiguration.isEventMeshServerUseTls(), // gRPC Configuration eventMeshGrpcConfiguration.getGrpcServerPort(), - eventMeshGrpcConfiguration.isEventMeshServerUseTls() - ); + eventMeshGrpcConfiguration.isEventMeshServerUseTls()); String result = JsonUtils.toJSONString(getConfigurationResponse); httpExchange.sendResponseHeaders(200, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); @@ -123,6 +147,17 @@ void get(HttpExchange httpExchange) throws IOException { } } + /** + * Handles the HTTP requests for {@code /configuration}. + *

+ * It delegates the handling to {@code preflight()} or {@code get()} methods + * based on the request method type (OPTIONS or GET). + *

+ * This method is an implementation of {@linkplain com.sun.net.httpserver.HttpHandler#handle(HttpExchange) HttpHandler.handle()} + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { switch (HttpMethod.valueOf(httpExchange.getRequestMethod())) { @@ -132,7 +167,7 @@ public void handle(HttpExchange httpExchange) throws IOException { case GET: get(httpExchange); break; - default: //do nothing + default: // do nothing break; } } 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 index b43df2fcff..59baa7bdcc 100644 --- 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 @@ -28,11 +28,34 @@ import java.io.IOException; import java.io.OutputStream; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /webhook/deleteWebHookConfig} endpoint + * and deletes an existing WebHook configuration + * according to the given {@linkplain org.apache.eventmesh.webhook.api.WebHookConfig WebHookConfig}. + *

+ * The implementation of + * {@linkplain org.apache.eventmesh.webhook.api.WebHookConfigOperation#deleteWebHookConfig WebHookConfigOperation} + * interface depends on the {@code eventMesh.webHook.operationMode} configuration in {@code eventmesh.properties}. + *

+ * For example, when {@code eventMesh.webHook.operationMode=file}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.FileWebHookConfigOperation#deleteWebHookConfig FileWebHookConfigOperation} + * method as implementation to delete the WebHook configuration file; + *

+ * When {@code eventMesh.webHook.operationMode=nacos}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.NacosWebHookConfigOperation#deleteWebHookConfig NacosWebHookConfigOperation} + * method as implementation to delete the WebHook configuration from Nacos. + *

+ * The {@linkplain org.apache.eventmesh.webhook.receive.storage.HookConfigOperationManager#deleteWebHookConfig HookConfigOperationManager} + * , another implementation of {@linkplain org.apache.eventmesh.webhook.api.WebHookConfigOperation WebHookConfigOperation} + * interface, is not used for this endpoint. + * + * @see AbstractHttpHandler + */ + @SuppressWarnings("restriction") @Slf4j @EventHttpHandler(path = "/webhook/deleteWebHookConfig") @@ -40,22 +63,36 @@ public class DeleteWebHookConfigHandler extends AbstractHttpHandler { private final WebHookConfigOperation operation; + /** + * Constructs a new instance with the specified WebHook config operation and HTTP handler manager. + * + * @param operation the WebHookConfigOperation implementation used to delete the WebHook config + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public DeleteWebHookConfigHandler(WebHookConfigOperation operation, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.operation = operation; } - + /** + * Handles requests by deleting a WebHook configuration. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + * + * @see org.apache.eventmesh.webhook.receive.storage.HookConfigOperationManager#deleteWebHookConfig + */ @Override public void handle(HttpExchange httpExchange) throws IOException { NetUtils.sendSuccessResponseHeaders(httpExchange); - // get requestBody and resolve to WebHookConfig + // Resolve to WebHookConfig String requestBody = NetUtils.parsePostBody(httpExchange); WebHookConfig webHookConfig = JsonUtils.parseObject(requestBody, WebHookConfig.class); try (OutputStream out = httpExchange.getResponseBody()) { - + // Delete the existing WebHookConfig Integer code = operation.deleteWebHookConfig(webHookConfig); // operating result String result = 1 == code ? "deleteWebHookConfig Succeed!" : "deleteWebHookConfig Failed!"; out.write(result.getBytes(Constants.DEFAULT_CHARSET)); diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/EventHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/EventHandler.java index 9d88a79523..d1d93bf2a0 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/EventHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/EventHandler.java @@ -47,18 +47,37 @@ import lombok.extern.slf4j.Slf4j; /** - * The event handler + * This class handles the {@code /event} endpoint, + * corresponding to the {@code eventmesh-dashboard} path {@code /event}. + *

+ * It is responsible for managing operations on events, + * including retrieving the event list and creating events. + *

+ * The GET method supports querying events by {@code topicName}, + * and uses {@code offset} and {@code length} parameters for pagination. + *

+ * An instance of {@link MQAdminWrapper} is used to interact with the messaging system. + * + * @see AbstractHttpHandler + * @see MQAdminWrapper */ + @Slf4j @EventHttpHandler(path = "/event") public class EventHandler extends AbstractHttpHandler { private final MQAdminWrapper admin; + /** + * Constructs a new instance with the specified connector plugin type and HTTP handler manager. + * + * @param connectorPluginType The name of event storage connector plugin. + * @param httpHandlerManager httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public EventHandler( String connectorPluginType, - HttpHandlerManager httpHandlerManager - ) { + HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); admin = new MQAdminWrapper(connectorPluginType); try { @@ -69,7 +88,13 @@ public EventHandler( } /** - * OPTIONS /event + * Handles the OPTIONS request first for {@code /event}. + *

+ * This method adds CORS (Cross-Origin Resource Sharing) response headers to + * the {@link HttpExchange} object and sends a 200 status code. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void preflight(HttpExchange httpExchange) throws IOException { httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); @@ -81,6 +106,17 @@ void preflight(HttpExchange httpExchange) throws IOException { out.close(); } + /** + * Converts a query string to a map of key-value pairs. + *

+ * This method takes a query string and parses it to create a map of key-value pairs, + * where each key and value are extracted from the query string separated by '='. + *

+ * If the query string is null, an empty map is returned. + * + * @param query the query string to convert to a map + * @return a map containing the key-value pairs from the query string + */ private Map queryToMap(String query) { if (query == null) { return new HashMap<>(); @@ -98,7 +134,12 @@ private Map queryToMap(String query) { } /** - * GET /event Return the list of event + * Handles the GET request for {@code /event}. + *

+ * This method retrieves the list of events from the {@link MQAdminWrapper} and returns it as a JSON response. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void get(HttpExchange httpExchange) { httpExchange.getResponseHeaders().add(EventMeshConstants.CONTENT_TYPE, EventMeshConstants.APPLICATION_JSON); @@ -120,8 +161,8 @@ void get(HttpExchange httpExchange) { List eventJsonList = new ArrayList<>(); for (CloudEvent event : eventList) { byte[] serializedEvent = Objects.requireNonNull(EventFormatProvider - .getInstance() - .resolveFormat(JsonFormat.CONTENT_TYPE)) + .getInstance() + .resolveFormat(JsonFormat.CONTENT_TYPE)) .serialize(event); eventJsonList.add(new String(serializedEvent, StandardCharsets.UTF_8)); } @@ -147,7 +188,12 @@ void get(HttpExchange httpExchange) { } /** - * POST /event Create an event + * Handles the POST request for {@code /event}. + *

+ * This method creates an event based on the request data, then returns {@code 200 OK}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void post(HttpExchange httpExchange) { httpExchange.getResponseHeaders().add(EventMeshConstants.CONTENT_TYPE, EventMeshConstants.APPLICATION_JSON); @@ -179,6 +225,17 @@ void post(HttpExchange httpExchange) { } } + /** + * Handles the HTTP requests for {@code /event}. + *

+ * It delegates the handling to {@code preflight()}, {@code get()} or {@code post()} methods + * based on the request method type (OPTIONS, GET or POST). + *

+ * This method is an implementation of {@linkplain com.sun.net.httpserver.HttpHandler#handle(HttpExchange) HttpHandler.handle()}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { switch (HttpMethod.valueOf(httpExchange.getRequestMethod())) { diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/GrpcClientHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/GrpcClientHandler.java index 1c73b098df..af16d9599c 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/GrpcClientHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/GrpcClientHandler.java @@ -41,29 +41,48 @@ import java.util.Objects; import java.util.Optional; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * The client handler + * This class handles the {@code /client/grpc} endpoint, + * corresponding to the {@code eventmesh-dashboard} path {@code /grpc}. + *

+ * It is responsible for managing operations on gRPC clients, + * including retrieving the information list of connected gRPC clients + * and deleting gRPC clients by disconnecting their connections based on the provided host and port. + * + * @see AbstractHttpHandler */ + @Slf4j @EventHttpHandler(path = "/client/grpc") public class GrpcClientHandler extends AbstractHttpHandler { private final EventMeshGrpcServer eventMeshGrpcServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshGrpcServer the gRPC server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} for an + * {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public GrpcClientHandler( - EventMeshGrpcServer eventMeshGrpcServer, HttpHandlerManager httpHandlerManager - ) { + EventMeshGrpcServer eventMeshGrpcServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshGrpcServer = eventMeshGrpcServer; } /** - * OPTIONS /client + * Handles the OPTIONS request first for {@code /client/grpc}. + *

+ * This method adds CORS (Cross-Origin Resource Sharing) response headers to + * the {@link HttpExchange} object and sends a 200 status code. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void preflight(HttpExchange httpExchange) throws IOException { httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); @@ -76,24 +95,34 @@ void preflight(HttpExchange httpExchange) throws IOException { } /** - * DELETE /client/grpc + * Handles the DELETE request for {@code /client/grpc}. + *

+ * This method deletes a connected gRPC client by disconnecting their connections + * based on the provided host and port, then returns {@code 200 OK}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void delete(HttpExchange httpExchange) throws IOException { try (OutputStream out = httpExchange.getResponseBody()) { + // Parse the request body string into a DeleteHTTPClientRequest object String request = HttpExchangeUtils.streamToString(httpExchange.getRequestBody()); DeleteGrpcClientRequest deleteGrpcClientRequest = JsonUtils.parseObject(request, DeleteGrpcClientRequest.class); String url = Objects.requireNonNull(deleteGrpcClientRequest).getUrl(); ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); Map> clientTable = consumerManager.getClientTable(); + // Find the client that matches the url to be deleted for (List clientList : clientTable.values()) { for (ConsumerGroupClient client : clientList) { if (Objects.equals(client.getUrl(), url)) { + // Call the deregisterClient method to close the gRPC client stream and remove it consumerManager.deregisterClient(client); } } } + // Set the response headers and send a 200 status code empty response httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); httpExchange.sendResponseHeaders(200, 0); } catch (Exception e) { @@ -111,10 +140,16 @@ void delete(HttpExchange httpExchange) throws IOException { } /** - * GET /client/grpc Return a response that contains the list of clients + * Handles the GET request for {@code /client/grpc}. + *

+ * This method retrieves the list of connected gRPC clients and returns it as a JSON response. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void list(HttpExchange httpExchange) throws IOException { OutputStream out = httpExchange.getResponseBody(); + // Set the response headers httpExchange.getResponseHeaders().add(EventMeshConstants.CONTENT_TYPE, EventMeshConstants.APPLICATION_JSON); httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); @@ -125,6 +160,7 @@ void list(HttpExchange httpExchange) throws IOException { ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); Map> clientTable = consumerManager.getClientTable(); for (List clientList : clientTable.values()) { + // Convert each Client object to GetClientResponse and add to getClientResponseList for (ConsumerGroupClient client : clientList) { GetClientResponse getClientResponse = new GetClientResponse( Optional.ofNullable(client.env).orElse(""), @@ -137,12 +173,12 @@ void list(HttpExchange httpExchange) throws IOException { Optional.ofNullable(client.idc).orElse(""), Optional.ofNullable(client.consumerGroup).orElse(""), "", - "gRPC" - ); + "gRPC"); getClientResponseList.add(getClientResponse); } } + // Sort the getClientResponseList by host and port getClientResponseList.sort((lhs, rhs) -> { if (lhs.getHost().equals(rhs.getHost())) { return lhs.getHost().compareTo(rhs.getHost()); @@ -150,6 +186,7 @@ void list(HttpExchange httpExchange) throws IOException { return Integer.compare(rhs.getPort(), lhs.getPort()); }); + // Convert getClientResponseList to JSON and send the response String result = JsonUtils.toJSONString(getClientResponseList); httpExchange.sendResponseHeaders(200, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); out.write(result.getBytes(Constants.DEFAULT_CHARSET)); @@ -175,6 +212,17 @@ void list(HttpExchange httpExchange) throws IOException { } } + /** + * Handles the HTTP requests for {@code /client/grpc}. + *

+ * It delegates the handling to {@code preflight()}, {@code list()} or {@code delete()} methods + * based on the request method type (OPTIONS, GET or DELETE). + *

+ * This method is an implementation of {@linkplain com.sun.net.httpserver.HttpHandler#handle(HttpExchange) HttpHandler.handle()}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { switch (HttpMethod.valueOf(httpExchange.getRequestMethod())) { diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/HTTPClientHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/HTTPClientHandler.java index 9a57f5c3d6..03fd1e54a7 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/HTTPClientHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/HTTPClientHandler.java @@ -39,29 +39,48 @@ import java.util.Objects; import java.util.Optional; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * The client handler + * This class handles the {@code /client/http} endpoint, + * corresponding to the {@code eventmesh-dashboard} path {@code /http}. + *

+ * It is responsible for managing operations on HTTP clients, + * including retrieving the information list of connected HTTP clients + * and deleting HTTP clients by disconnecting their connections based on the provided host and port. + * + * @see AbstractHttpHandler */ + @Slf4j @EventHttpHandler(path = "/client/http") public class HTTPClientHandler extends AbstractHttpHandler { private final EventMeshHTTPServer eventMeshHTTPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshHTTPServer the HTTP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} for an + * {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public HTTPClientHandler( - EventMeshHTTPServer eventMeshHTTPServer, HttpHandlerManager httpHandlerManager - ) { + EventMeshHTTPServer eventMeshHTTPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshHTTPServer = eventMeshHTTPServer; } /** - * OPTIONS /client + * Handles the OPTIONS request first for {@code /client/http}. + *

+ * This method adds CORS (Cross-Origin Resource Sharing) response headers to + * the {@link HttpExchange} object and sends a 200 status code. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void preflight(HttpExchange httpExchange) throws IOException { httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); @@ -74,18 +93,27 @@ void preflight(HttpExchange httpExchange) throws IOException { } /** - * DELETE /client/http + * Handles the DELETE request for {@code /client/http}. + *

+ * This method deletes a connected HTTP client by disconnecting their connections + * based on the provided host and port, then returns {@code 200 OK}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void delete(HttpExchange httpExchange) throws IOException { try (OutputStream out = httpExchange.getResponseBody()) { + // Parse the request body string into a DeleteHTTPClientRequest object String request = HttpExchangeUtils.streamToString(httpExchange.getRequestBody()); DeleteHTTPClientRequest deleteHTTPClientRequest = JsonUtils.parseObject(request, DeleteHTTPClientRequest.class); String url = Objects.requireNonNull(deleteHTTPClientRequest).getUrl(); for (List clientList : eventMeshHTTPServer.getSubscriptionManager().getLocalClientInfoMapping().values()) { + // Find the client that matches the url to be deleted clientList.removeIf(client -> Objects.equals(client.getUrl(), url)); } + // Set the response headers and send a 200 status code empty response httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); httpExchange.sendResponseHeaders(200, 0); } catch (Exception e) { @@ -103,10 +131,16 @@ void delete(HttpExchange httpExchange) throws IOException { } /** - * GET /client/http Return a response that contains the list of clients + * Handles the GET request for {@code /client/http}. + *

+ * This method retrieves the list of connected HTTP clients and returns it as a JSON response. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void list(HttpExchange httpExchange) throws IOException { OutputStream out = httpExchange.getResponseBody(); + // Set the response headers httpExchange.getResponseHeaders().add(EventMeshConstants.CONTENT_TYPE, EventMeshConstants.APPLICATION_JSON); httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); @@ -115,6 +149,7 @@ void list(HttpExchange httpExchange) throws IOException { List getClientResponseList = new ArrayList<>(); for (List clientList : eventMeshHTTPServer.getSubscriptionManager().getLocalClientInfoMapping().values()) { + // Convert each Client object to GetClientResponse and add to getClientResponseList for (Client client : clientList) { GetClientResponse getClientResponse = new GetClientResponse( Optional.ofNullable(client.getEnv()).orElse(""), @@ -134,6 +169,7 @@ void list(HttpExchange httpExchange) throws IOException { } } + // Sort the getClientResponseList by host and port getClientResponseList.sort((lhs, rhs) -> { if (lhs.getHost().equals(rhs.getHost())) { return lhs.getHost().compareTo(rhs.getHost()); @@ -141,6 +177,7 @@ void list(HttpExchange httpExchange) throws IOException { return Integer.compare(rhs.getPort(), lhs.getPort()); }); + // Convert getClientResponseList to JSON and send the response String result = JsonUtils.toJSONString(getClientResponseList); httpExchange.sendResponseHeaders(200, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); out.write(result.getBytes(Constants.DEFAULT_CHARSET)); @@ -166,6 +203,17 @@ void list(HttpExchange httpExchange) throws IOException { } } + /** + * Handles the HTTP requests for {@code /client/http}. + *

+ * It delegates the handling to {@code preflight()}, {@code list()} or {@code delete()} methods + * based on the request method type (OPTIONS, GET or DELETE). + *

+ * This method is an implementation of {@linkplain com.sun.net.httpserver.HttpHandler#handle(HttpExchange) HttpHandler.handle()}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { switch (HttpMethod.valueOf(httpExchange.getRequestMethod())) { 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 index dfbfd9f26d..a7934146a4 100644 --- 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 @@ -28,11 +28,35 @@ import java.io.IOException; import java.io.OutputStream; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /webhook/insertWebHookConfig} endpoint + * and adds a new WebHook configuration + * according to the given {@linkplain org.apache.eventmesh.webhook.api.WebHookConfig WebHookConfig}, + * if there isn't an existing duplicate configuration already. + *

+ * The implementation of + * {@linkplain org.apache.eventmesh.webhook.api.WebHookConfigOperation#insertWebHookConfig WebHookConfigOperation} + * interface depends on the {@code eventMesh.webHook.operationMode} configuration in {@code eventmesh.properties}. + *

+ * For example, when {@code eventMesh.webHook.operationMode=file}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.FileWebHookConfigOperation#insertWebHookConfig FileWebHookConfigOperation} + * method as implementation to save the WebHook configuration as a file; + *

+ * When {@code eventMesh.webHook.operationMode=nacos}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.NacosWebHookConfigOperation#insertWebHookConfig NacosWebHookConfigOperation} + * method as implementation to save the WebHook configuration into Nacos. + *

+ * The {@linkplain org.apache.eventmesh.webhook.receive.storage.HookConfigOperationManager#insertWebHookConfig HookConfigOperationManager} + * , another implementation of {@linkplain org.apache.eventmesh.webhook.api.WebHookConfigOperation WebHookConfigOperation} + * interface, is not used for this endpoint. + * + * @see AbstractHttpHandler + */ + @SuppressWarnings("restriction") @Slf4j @EventHttpHandler(path = "/webhook/insertWebHookConfig") @@ -40,20 +64,34 @@ public class InsertWebHookConfigHandler extends AbstractHttpHandler { private final WebHookConfigOperation operation; + /** + * Constructs a new instance with the specified WebHook config operation and HTTP handler manager. + * + * @param operation the WebHookConfigOperation implementation used to insert the WebHook config + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public InsertWebHookConfigHandler(WebHookConfigOperation operation, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.operation = operation; } + /** + * Handles requests by adding a WebHook configuration. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { NetUtils.sendSuccessResponseHeaders(httpExchange); - // get requestBody and resolve to WebHookConfig + // Resolve to WebHookConfig String requestBody = NetUtils.parsePostBody(httpExchange); WebHookConfig webHookConfig = JsonUtils.parseObject(requestBody, WebHookConfig.class); try (OutputStream out = httpExchange.getResponseBody()) { + // Add the WebHookConfig if no existing duplicate configuration is found Integer code = operation.insertWebHookConfig(webHookConfig); // operating result String result = 1 == code ? "insertWebHookConfig Succeed!" : "insertWebHookConfig Failed!"; out.write(result.getBytes(Constants.DEFAULT_CHARSET)); diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/MetaHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/MetaHandler.java new file mode 100644 index 0000000000..d29dbd2d97 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/MetaHandler.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.admin.handler; + +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.enums.HttpMethod; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.admin.controller.HttpHandlerManager; +import org.apache.eventmesh.runtime.admin.response.Error; +import org.apache.eventmesh.runtime.admin.response.GetRegistryResponse; +import org.apache.eventmesh.runtime.common.EventHttpHandler; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.meta.MetaStorage; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; + +import com.sun.net.httpserver.HttpExchange; + +import lombok.extern.slf4j.Slf4j; + +/** + * This class handles the {@code /registry} endpoint, + * corresponding to the {@code eventmesh-dashboard} path {@code /registry}. + *

+ * This handler is responsible for retrieving a list of EventMesh clusters from the + * {@link MetaStorage} object, encapsulate them into a list of {@link GetRegistryResponse} objects, + * and sort them by {@code EventMeshClusterName}. + * + * @see AbstractHttpHandler + */ + +@Slf4j +@EventHttpHandler(path = "/meta") +public class MetaHandler extends AbstractHttpHandler { + + private final MetaStorage eventMeshMetaStorage; + + /** + * Constructs a new instance with the specified {@link MetaStorage} and {@link HttpHandlerManager}. + * + * @param eventMeshMetaStorage The {@link MetaStorage} instance used for retrieving EventMesh cluster information. + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@linkplain com.sun.net.httpserver.HttpServer HttpServer}. + */ + public MetaHandler(MetaStorage eventMeshMetaStorage, + HttpHandlerManager httpHandlerManager) { + super(httpHandlerManager); + this.eventMeshMetaStorage = eventMeshMetaStorage; + } + + /** + * Handles the OPTIONS request first for {@code /registry}. + *

+ * This method adds CORS (Cross-Origin Resource Sharing) response headers to + * the {@link HttpExchange} object and sends a 200 status code. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ + void preflight(HttpExchange httpExchange) throws IOException { + httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); + httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_METHODS, "*"); + httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_AGE, EventMeshConstants.MAX_AGE); + httpExchange.sendResponseHeaders(200, 0); + OutputStream out = httpExchange.getResponseBody(); + out.close(); + } + + /** + * Handles the GET request for {@code /registry}. + *

+ * This method retrieves a list of EventMesh clusters and returns it as a JSON response. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ + void get(HttpExchange httpExchange) throws IOException { + httpExchange.getResponseHeaders().add(EventMeshConstants.CONTENT_TYPE, EventMeshConstants.APPLICATION_JSON); + httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); + + try (OutputStream out = httpExchange.getResponseBody()) { + try { + List getRegistryResponseList = new ArrayList<>(); + List eventMeshDataInfos = eventMeshMetaStorage.findAllEventMeshInfo(); + for (EventMeshDataInfo eventMeshDataInfo : eventMeshDataInfos) { + GetRegistryResponse getRegistryResponse = new GetRegistryResponse( + eventMeshDataInfo.getEventMeshClusterName(), + eventMeshDataInfo.getEventMeshName(), + eventMeshDataInfo.getEndpoint(), + eventMeshDataInfo.getLastUpdateTimestamp(), + eventMeshDataInfo.getMetadata().toString()); + getRegistryResponseList.add(getRegistryResponse); + } + getRegistryResponseList.sort(Comparator.comparing(GetRegistryResponse::getEventMeshClusterName)); + + String result = JsonUtils.toJSONString(getRegistryResponseList); + httpExchange.sendResponseHeaders(200, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); + out.write(result.getBytes(Constants.DEFAULT_CHARSET)); + } catch (NullPointerException e) { + // registry not initialized, return empty list + String result = JsonUtils.toJSONString(new ArrayList<>()); + httpExchange.sendResponseHeaders(200, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); + out.write(result.getBytes(Constants.DEFAULT_CHARSET)); + } catch (Exception e) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + e.printStackTrace(printWriter); + printWriter.flush(); + String stackTrace = writer.toString(); + + Error error = new Error(e.toString(), stackTrace); + String result = JsonUtils.toJSONString(error); + httpExchange.sendResponseHeaders(500, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); + out.write(result.getBytes(Constants.DEFAULT_CHARSET)); + } + } catch (IOException e) { + log.warn("out close failed...", e); + } + } + + /** + * Handles the HTTP requests for {@code /registry}. + *

+ * It delegates the handling to {@code preflight()} or {@code get()} methods + * based on the request method type (OPTIONS or GET). + *

+ * This method is an implementation of {@linkplain com.sun.net.httpserver.HttpHandler#handle(HttpExchange) HttpHandler.handle()} + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ + @Override + public void handle(HttpExchange httpExchange) throws IOException { + switch (HttpMethod.valueOf(httpExchange.getRequestMethod())) { + case OPTIONS: + preflight(httpExchange); + break; + case GET: + get(httpExchange); + break; + default: + break; + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/MetricsHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/MetricsHandler.java index 2fc89ed9b3..39f71f0924 100755 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/MetricsHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/MetricsHandler.java @@ -36,11 +36,20 @@ import java.io.StringWriter; import java.util.Objects; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the {@code /metrics} endpoint, + * corresponding to the {@code eventmesh-dashboard} path {@code /metrics}. + *

+ * This handler is responsible for retrieving summary information of metrics, + * including HTTP and TCP metrics. + * + * @see AbstractHttpHandler + */ + @Slf4j @EventHttpHandler(path = "/metrics") public class MetricsHandler extends AbstractHttpHandler { @@ -48,6 +57,14 @@ public class MetricsHandler extends AbstractHttpHandler { private final HttpSummaryMetrics httpSummaryMetrics; private final TcpSummaryMetrics tcpSummaryMetrics; + /** + * Constructs a new instance with the provided EventMesh server instance and HTTP handler manager. + * + * @param eventMeshHTTPServer the HTTP server instance of EventMesh + * @param eventMeshTcpServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public MetricsHandler(EventMeshHTTPServer eventMeshHTTPServer, EventMeshTCPServer eventMeshTcpServer, HttpHandlerManager httpHandlerManager) { @@ -57,7 +74,13 @@ public MetricsHandler(EventMeshHTTPServer eventMeshHTTPServer, } /** - * OPTIONS /metrics + * Handles the OPTIONS request first for {@code /metrics}. + *

+ * This method adds CORS (Cross-Origin Resource Sharing) response headers to + * the {@link HttpExchange} object and sends a 200 status code. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void preflight(HttpExchange httpExchange) throws IOException { httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); @@ -70,7 +93,12 @@ void preflight(HttpExchange httpExchange) throws IOException { } /** - * GET /metrics Return a response that contains a summary of metrics + * Handles the GET request for {@code /metrics}. + *

+ * This method retrieves the EventMesh metrics summary and returns it as a JSON response. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void get(HttpExchange httpExchange) throws IOException { OutputStream out = httpExchange.getResponseBody(); @@ -120,8 +148,7 @@ void get(HttpExchange httpExchange) throws IOException { tcpSummaryMetrics.getEventMesh2clientTPS(), tcpSummaryMetrics.getAllTPS(), tcpSummaryMetrics.getAllConnections(), - tcpSummaryMetrics.getSubTopicNum() - ); + tcpSummaryMetrics.getSubTopicNum()); String result = JsonUtils.toJSONString(getMetricsResponse); byte[] bytes = Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET); httpExchange.sendResponseHeaders(200, bytes.length); @@ -149,7 +176,17 @@ void get(HttpExchange httpExchange) throws IOException { } } - + /** + * Handles the HTTP requests for {@code /metrics}. + *

+ * It delegates the handling to {@code preflight()} or {@code get()} methods + * based on the request method type (OPTIONS or GET). + *

+ * This method is an implementation of {@linkplain com.sun.net.httpserver.HttpHandler#handle(HttpExchange) HttpHandler.handle()} + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { switch (HttpMethod.valueOf(httpExchange.getRequestMethod())) { 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 index 18741c7e50..77da3d33bb 100644 --- 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 @@ -32,13 +32,24 @@ import java.io.OutputStream; import java.util.Map; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * query recommend eventmesh + * This class handles the HTTP requests of {@code /eventMesh/recommend} endpoint, + * which is used to calculate and return the recommended EventMesh server node to the client + * based on the provided {@code group} and {@code purpose} parameters. + *

+ * Parameters: + *

    + *
  • client group: {@code group} | Example: {@code EventmeshTestGroup}
  • + *
  • client purpose: {@code purpose} | Example: {@code sub}
  • + *
+ * It uses an {@link EventMeshRecommendStrategy} which is implemented by {@link EventMeshRecommendImpl} + * to calculate the recommended EventMesh server node. + * + * @see AbstractHttpHandler */ @Slf4j @EventHttpHandler(path = "/eventMesh/recommend") @@ -46,22 +57,37 @@ public class QueryRecommendEventMeshHandler extends AbstractHttpHandler { private final EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public QueryRecommendEventMeshHandler(EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; } + /** + * Handles requests by calculating a recommended EventMesh server node. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { String result = ""; try (OutputStream out = httpExchange.getResponseBody()) { - if (!eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerRegistryEnable()) { + if (!eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerMetaStorageEnable()) { throw new Exception("registry enable config is false, not support"); } String queryString = httpExchange.getRequestURI().getQuery(); Map queryStringInfo = NetUtils.formData2Dic(queryString); + // Extract parameters from the query string String group = queryStringInfo.get(EventMeshConstants.MANAGE_GROUP); String purpose = queryStringInfo.get(EventMeshConstants.MANAGE_PURPOSE); + // Check the validity of the parameters if (StringUtils.isBlank(group) || StringUtils.isBlank(purpose)) { NetUtils.sendSuccessResponseHeaders(httpExchange); result = "params illegal!"; @@ -70,6 +96,7 @@ public void handle(HttpExchange httpExchange) throws IOException { } EventMeshRecommendStrategy eventMeshRecommendStrategy = new EventMeshRecommendImpl(eventMeshTCPServer); + // Calculate the recommended EventMesh node according to the given group and purpose String recommendEventMeshResult = eventMeshRecommendStrategy.calculateRecommendEventMesh(group, purpose); result = (recommendEventMeshResult == null) ? "null" : recommendEventMeshResult; log.info("recommend eventmesh:{},group:{},purpose:{}", result, group, purpose); 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 index 55e726e455..a34ef811f4 100644 --- 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 @@ -30,12 +30,42 @@ import java.io.IOException; import java.io.OutputStream; - +import java.util.Objects; import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /webhook/queryWebHookConfigById} endpoint + * and returns the corresponding WebHook configuration information + * based on the WebHook callback path specified in {@linkplain org.apache.eventmesh.webhook.api.WebHookConfig WebHookConfig}. + *

+ * Parameters: + *

    + *
  • WebHook callback path: {@code callbackPath} | Example: {@code /webhook/github/eventmesh/all}
  • + *
  • WebHook manufacturer name: {@code manufacturerName} | Example: {@code github}
  • + *
+ * The implementation of + * {@linkplain org.apache.eventmesh.webhook.api.WebHookConfigOperation#queryWebHookConfigById WebHookConfigOperation} + * interface depends on the {@code eventMesh.webHook.operationMode} configuration in {@code eventmesh.properties}. + *

+ * For example, when {@code eventMesh.webHook.operationMode=file}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.FileWebHookConfigOperation#queryWebHookConfigById FileWebHookConfigOperation} + * method as implementation to retrieve the WebHook configuration from a file; + *

+ * When {@code eventMesh.webHook.operationMode=nacos}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.NacosWebHookConfigOperation#queryWebHookConfigById NacosWebHookConfigOperation} + * method as implementation to retrieve the WebHook configuration from Nacos. + *

+ * After this, the {@linkplain org.apache.eventmesh.webhook.receive.WebHookController#execute WebHookController} + * will use + * {@linkplain org.apache.eventmesh.webhook.receive.storage.HookConfigOperationManager#queryWebHookConfigById HookConfigOperationManager} + * to retrieve existing WebHook configuration by callback path when processing received WebHook data from manufacturers. + * + * @see AbstractHttpHandler + */ + @SuppressWarnings("restriction") @Slf4j @EventHttpHandler(path = "/webhook/queryWebHookConfigById") @@ -43,24 +73,37 @@ public class QueryWebHookConfigByIdHandler extends AbstractHttpHandler { private final WebHookConfigOperation operation; + /** + * Constructs a new instance with the specified WebHook config operation and HTTP handler manager. + * + * @param operation the WebHookConfigOperation implementation used to query the WebHook config + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public QueryWebHookConfigByIdHandler(WebHookConfigOperation operation, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.operation = operation; } - + /** + * Handles requests by retrieving a WebHook configuration. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { - NetUtils.sendSuccessResponseHeaders(httpExchange); httpExchange.getResponseHeaders().add(CONTENT_TYPE, APPLICATION_JSON); + NetUtils.sendSuccessResponseHeaders(httpExchange); - // get requestBody and resolve to WebHookConfig + // Resolve to WebHookConfig String requestBody = NetUtils.parsePostBody(httpExchange); WebHookConfig webHookConfig = JsonUtils.parseObject(requestBody, WebHookConfig.class); try (OutputStream out = httpExchange.getResponseBody()) { + // Retrieve the WebHookConfig by callback path WebHookConfig result = operation.queryWebHookConfigById(webHookConfig); // operating result - out.write(JsonUtils.toJSONString(result).getBytes(Constants.DEFAULT_CHARSET)); + out.write(Objects.requireNonNull(JsonUtils.toJSONString(result)).getBytes(Constants.DEFAULT_CHARSET)); } catch (Exception e) { log.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 index f49e7942d3..63c0f82edf 100644 --- 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 @@ -33,12 +33,36 @@ import java.util.List; import java.util.Objects; - import com.fasterxml.jackson.databind.JsonNode; import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /webhook/queryWebHookConfigByManufacturer} endpoint + * and returns a list of WebHook configurations + * based on the WebHook manufacturer name (such as github) specified in {@linkplain org.apache.eventmesh.webhook.api.WebHookConfig WebHookConfig}. + *

+ * The implementation of + * {@linkplain org.apache.eventmesh.webhook.api.WebHookConfigOperation#queryWebHookConfigByManufacturer WebHookConfigOperation} + * interface depends on the {@code eventMesh.webHook.operationMode} configuration in {@code eventmesh.properties}. + *

+ * For example, when {@code eventMesh.webHook.operationMode=file}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.FileWebHookConfigOperation#queryWebHookConfigByManufacturer FileWebHookConfigOperation} + * method as implementation to retrieve the WebHook configuration from a file; + *

+ * When {@code eventMesh.webHook.operationMode=nacos}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.NacosWebHookConfigOperation#queryWebHookConfigByManufacturer NacosWebHookConfigOperation} + * method as implementation to retrieve the WebHook configuration from Nacos. + *

+ * The + * {@linkplain org.apache.eventmesh.webhook.receive.storage.HookConfigOperationManager#queryWebHookConfigByManufacturer HookConfigOperationManager} + * , another implementation of {@linkplain org.apache.eventmesh.webhook.api.WebHookConfigOperation WebHookConfigOperation} + * interface, is not used for this endpoint. + * + * @see AbstractHttpHandler + */ + @SuppressWarnings("restriction") @Slf4j @EventHttpHandler(path = "/webhook/queryWebHookConfigByManufacturer") @@ -46,6 +70,13 @@ public class QueryWebHookConfigByManufacturerHandler extends AbstractHttpHandler private final transient WebHookConfigOperation operation; + /** + * Constructs a new instance with the specified WebHook config operation and HTTP handler manager. + * + * @param operation the WebHookConfigOperation implementation used to query the WebHook config + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public QueryWebHookConfigByManufacturerHandler(WebHookConfigOperation operation, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); @@ -55,25 +86,31 @@ public QueryWebHookConfigByManufacturerHandler(WebHookConfigOperation operation, } - + /** + * Handles requests by retrieving a list of WebHook configurations. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { Objects.requireNonNull(httpExchange, "httpExchange can not be null"); - NetUtils.sendSuccessResponseHeaders(httpExchange); httpExchange.getResponseHeaders().add(CONTENT_TYPE, APPLICATION_JSON); + NetUtils.sendSuccessResponseHeaders(httpExchange); - // get requestBody and resolve to WebHookConfig + // Resolve to WebHookConfig JsonNode node = JsonUtils.getJsonNode(NetUtils.parsePostBody(httpExchange)); Objects.requireNonNull(node, "JsonNode can not be null"); - WebHookConfig webHookConfig = JsonUtils.parseObject(node.get("webHookConfig").toString(), WebHookConfig.class); + WebHookConfig webHookConfig = JsonUtils.parseObject(node.toString(), WebHookConfig.class); Integer pageNum = Integer.valueOf(node.get("pageNum").toString()); Integer pageSize = Integer.valueOf(node.get("pageSize").toString()); try (OutputStream out = httpExchange.getResponseBody()) { + // Retrieve the WebHookConfig list by manufacturer name List result = operation.queryWebHookConfigByManufacturer(webHookConfig, pageNum, pageSize); // operating result - out.write(JsonUtils.toJSONString(result).getBytes(Constants.DEFAULT_CHARSET)); + out.write(Objects.requireNonNull(JsonUtils.toJSONString(result)).getBytes(Constants.DEFAULT_CHARSET)); } catch (Exception e) { log.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 index b886e8b62d..bfd5ad4960 100644 --- 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 @@ -35,33 +35,66 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /clientManage/redirectClientByIpPort} endpoint, + * which is used to redirect matching clients to a target EventMesh server node + * based on the provided IP address and port. + *

+ * The request must specify the client's and target EventMesh node's IP and port. + *

+ * Parameters: + *

    + *
  • client's IP: {@code ip}
  • + *
  • client's port: {@code port}
  • + *
  • target EventMesh node's IP: {@code desteventmeshIp}
  • + *
  • target EventMesh node's port: {@code desteventmeshport}
  • + *
+ * It uses the {@link EventMeshTcp2Client#redirectClient2NewEventMesh} method to redirect the matching client. + * + * @see AbstractHttpHandler + */ + @Slf4j @EventHttpHandler(path = "/clientManage/redirectClientByIpPort") public class RedirectClientByIpPortHandler extends AbstractHttpHandler { private final EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public RedirectClientByIpPortHandler(EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; } + /** + * Handles requests by redirecting matching clients to a target EventMesh server node. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { String result = ""; try (OutputStream out = httpExchange.getResponseBody()) { String queryString = httpExchange.getRequestURI().getQuery(); Map queryStringInfo = NetUtils.formData2Dic(queryString); + // Extract parameters from the query string 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); + // Check the validity of the parameters if (StringUtils.isBlank(ip) || !StringUtils.isNumeric(port) || StringUtils.isBlank(destEventMeshIp) || StringUtils.isBlank(destEventMeshPort) || !StringUtils.isNumeric(destEventMeshPort)) { @@ -72,41 +105,42 @@ public void handle(HttpExchange httpExchange) throws IOException { } log.info("redirectClientByIpPort in admin,ip:{},port:{},destIp:{},destPort:{}====================", ip, port, destEventMeshIp, destEventMeshPort); + // Retrieve the mapping between Sessions and their corresponding client address ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); StringBuilder redirectResult = new StringBuilder(); try { if (!sessionMap.isEmpty()) { + // Iterate through the sessionMap to find matching sessions where the client's IP and port match the given ones for (Session session : sessionMap.values()) { + // For each matching session found, redirect the client + // to the new EventMesh node specified by given EventMesh IP and port. if (session.getClient().getHost().equals(ip) && String.valueOf( session.getClient().getPort()).equals(port)) { redirectResult.append("|"); - redirectResult.append( - EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer, - destEventMeshIp, Integer.parseInt(destEventMeshPort), - session, clientSessionGroupMapping)); + redirectResult.append(EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer.getTcpThreadPoolGroup(), + destEventMeshIp, Integer.parseInt(destEventMeshPort), + session, clientSessionGroupMapping)); } } } } catch (Exception e) { log.error("clientManage|redirectClientByIpPort|fail|ip={}|port={}|destEventMeshIp" + - "={}|destEventMeshPort={},errMsg={}", ip, port, destEventMeshIp, destEventMeshPort, e); + "={}|destEventMeshPort={}", 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.toString(), e - .getMessage()); + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s}, errorMsg : %s", + sessionMap.size(), ip, port, destEventMeshIp, destEventMeshPort, redirectResult, e.getMessage()); NetUtils.sendSuccessResponseHeaders(httpExchange); out.write(result.getBytes(Constants.DEFAULT_CHARSET)); return; } + // Serialize the result of redirection into output stream 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.toString()); + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s} ", + sessionMap.size(), ip, port, destEventMeshIp, destEventMeshPort, redirectResult); NetUtils.sendSuccessResponseHeaders(httpExchange); out.write(result.getBytes(Constants.DEFAULT_CHARSET)); } catch (Exception 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 index a4cbaf1662..0b9e8f52c4 100644 --- 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 @@ -35,35 +35,64 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * redirect subsystem for path + * This class handles the HTTP requests of {@code /clientManage/redirectClientByPath} endpoint, + * which is used to redirect matching clients to a target EventMesh server node + * based on the provided client UserAgent path. + *

+ * The request must specify the client's path and target EventMesh node's IP and port. + *

+ * Parameters: + *

    + *
  • client's path: {@code path} | Example: {@code /data/app/umg_proxy}
  • + *
  • target EventMesh node's IP: {@code desteventmeshIp}
  • + *
  • target EventMesh node's port: {@code desteventmeshport}
  • + *
+ * It uses the {@link EventMeshTcp2Client#redirectClient2NewEventMesh} method to redirect the matching client. + * + * @see AbstractHttpHandler */ + @Slf4j @EventHttpHandler(path = "/clientManage/redirectClientByPath") public class RedirectClientByPathHandler extends AbstractHttpHandler { private final EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public RedirectClientByPathHandler(EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; } + /** + * Handles requests by redirecting matching clients to a target EventMesh server node. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { String result = ""; try (OutputStream out = httpExchange.getResponseBody()) { String queryString = httpExchange.getRequestURI().getQuery(); Map queryStringInfo = NetUtils.formData2Dic(queryString); + // Extract parameters from the query string String path = queryStringInfo.get(EventMeshConstants.MANAGE_PATH); String destEventMeshIp = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_IP); String destEventMeshPort = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_PORT); + // Check the validity of the parameters if (StringUtils.isBlank(path) || StringUtils.isBlank(destEventMeshIp) || StringUtils.isBlank(destEventMeshPort) || !StringUtils.isNumeric(destEventMeshPort)) { @@ -74,15 +103,19 @@ public void handle(HttpExchange httpExchange) throws IOException { } log.info("redirectClientByPath in admin,path:{},destIp:{},destPort:{}====================", path, destEventMeshIp, destEventMeshPort); + // Retrieve the mapping between Sessions and their corresponding client address ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); StringBuilder redirectResult = new StringBuilder(); try { if (!sessionMap.isEmpty()) { + // Iterate through the sessionMap to find matching sessions where the client's path matches the given param for (Session session : sessionMap.values()) { + // For each matching session found, redirect the client + // to the new EventMesh node specified by given EventMesh IP and port. if (session.getClient().getPath().contains(path)) { redirectResult.append("|"); - redirectResult.append(EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer, + redirectResult.append(EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer.getTcpThreadPoolGroup(), destEventMeshIp, Integer.parseInt(destEventMeshPort), session, clientSessionGroupMapping)); } @@ -91,19 +124,18 @@ public void handle(HttpExchange httpExchange) throws IOException { } catch (Exception e) { log.error("clientManage|redirectClientByPath|fail|path={}|destEventMeshIp" + - "={}|destEventMeshPort={},errMsg={}", path, destEventMeshIp, destEventMeshPort, e); + "={}|destEventMeshPort={}", 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()); + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s}, errorMsg : %s", + sessionMap.size(), path, destEventMeshIp, destEventMeshPort, redirectResult, e.getMessage()); NetUtils.sendSuccessResponseHeaders(httpExchange); out.write(result.getBytes(Constants.DEFAULT_CHARSET)); return; } result = String.format("redirectClientByPath success! sessionMap size {%d}, {path=%s " - + - "destEventMeshIp=%s destEventMeshPort=%s}, result {%s} ", + + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s} ", sessionMap.size(), path, destEventMeshIp, destEventMeshPort, redirectResult); NetUtils.sendSuccessResponseHeaders(httpExchange); out.write(result.getBytes(Constants.DEFAULT_CHARSET)); 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 index 42ecf69d6c..6edc3fda8b 100644 --- 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 @@ -36,36 +36,64 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * redirect subsystem for subsys and dcn + * This class handles the HTTP requests of {@code /clientManage/redirectClientBySubSystem} endpoint, + * which is used to redirect matching clients to a target EventMesh server node + * based on the provided client subsystem id in a Data Communication Network (DCN). + *

+ * The request must specify the client's subsystem id and target EventMesh node's IP and port. + *

+ * Parameters: + *

    + *
  • client's subsystem id: {@code subsystem} | Example: {@code 5023}
  • + *
  • target EventMesh node's IP: {@code desteventmeshIp}
  • + *
  • target EventMesh node's port: {@code desteventmeshport}
  • + *
+ * It uses the {@link EventMeshTcp2Client#redirectClient2NewEventMesh} method to redirect the matching client. + * + * @see AbstractHttpHandler */ + @Slf4j @EventHttpHandler(path = "/clientManage/redirectClientBySubSystem") public class RedirectClientBySubSystemHandler extends AbstractHttpHandler { private final transient EventMeshTCPServer eventMeshTCPServer; - public RedirectClientBySubSystemHandler(final EventMeshTCPServer eventMeshTCPServer, - final HttpHandlerManager httpHandlerManager) { + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ + public RedirectClientBySubSystemHandler(final EventMeshTCPServer eventMeshTCPServer, final HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; } + /** + * Handles requests by redirecting matching clients to a target EventMesh server node. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(final HttpExchange httpExchange) throws IOException { Objects.requireNonNull(httpExchange, "httpExchange can not be null"); try (OutputStream out = httpExchange.getResponseBody()) { final Map queryStringInfo = NetUtils.formData2Dic(httpExchange.getRequestURI().getQuery()); + // Extract parameters from the query string final String subSystem = queryStringInfo.get(EventMeshConstants.MANAGE_SUBSYSTEM); final String destEventMeshIp = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_IP); final String destEventMeshPort = queryStringInfo.get(EventMeshConstants.MANAGE_DEST_PORT); + // Check the validity of the parameters if (!StringUtils.isNumeric(subSystem) || StringUtils.isBlank(destEventMeshIp) || StringUtils.isBlank(destEventMeshPort) || !StringUtils.isNumeric(destEventMeshPort)) { @@ -73,20 +101,22 @@ public void handle(final HttpExchange httpExchange) throws IOException { out.write("params illegal!".getBytes(Constants.DEFAULT_CHARSET)); return; } - if (log.isInfoEnabled()) { - log.info("redirectClientBySubSystem in admin,subsys:{},destIp:{},destPort:{}====================", - subSystem, destEventMeshIp, destEventMeshPort); - } + log.info("redirectClientBySubSystem in admin,subsys:{},destIp:{},destPort:{}====================", + subSystem, destEventMeshIp, destEventMeshPort); + // Retrieve the mapping between Sessions and their corresponding client address final ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); final ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); final StringBuilder redirectResult = new StringBuilder(); try { if (!sessionMap.isEmpty()) { + // Iterate through the sessionMap to find matching sessions where the client's subsystem id matches the given param for (final Session session : sessionMap.values()) { + // For each matching session found, redirect the client + // to the new EventMesh node specified by given EventMesh IP and port. if (session.getClient().getSubsystem().equals(subSystem)) { redirectResult.append('|') - .append(EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer, + .append(EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer.getTcpThreadPoolGroup(), destEventMeshIp, Integer.parseInt(destEventMeshPort), session, clientSessionGroupMapping)); } @@ -94,22 +124,19 @@ public void handle(final HttpExchange httpExchange) throws IOException { } } catch (Exception e) { log.error("clientManage|redirectClientBySubSystem|fail|subSystem={}|destEventMeshIp" - + - "={}|destEventMeshPort={},errMsg={}", subSystem, destEventMeshIp, destEventMeshPort, e); + + "={}|destEventMeshPort={}", subSystem, destEventMeshIp, destEventMeshPort, e); NetUtils.sendSuccessResponseHeaders(httpExchange); out.write(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()).getBytes(Constants.DEFAULT_CHARSET)); + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s}, errorMsg : %s", + sessionMap.size(), subSystem, destEventMeshIp, destEventMeshPort, redirectResult, e.getMessage()) + .getBytes(Constants.DEFAULT_CHARSET)); return; } NetUtils.sendSuccessResponseHeaders(httpExchange); out.write(String.format("redirectClientBySubSystem success! sessionMap size {%d}, {subSystem=%s " - + - "destEventMeshIp=%s destEventMeshPort=%s}, result {%s} ", - sessionMap.size(), subSystem, destEventMeshIp, destEventMeshPort, redirectResult) + + "destEventMeshIp=%s destEventMeshPort=%s}, result {%s} ", + sessionMap.size(), subSystem, destEventMeshIp, destEventMeshPort, redirectResult) .getBytes(Constants.DEFAULT_CHARSET)); } catch (Exception e) { log.error("redirectClientBySubSystem fail...", e); diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RegistryHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RegistryHandler.java deleted file mode 100755 index cd85b1dbaa..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/RegistryHandler.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.runtime.admin.handler; - -import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; -import org.apache.eventmesh.common.Constants; -import org.apache.eventmesh.common.enums.HttpMethod; -import org.apache.eventmesh.common.utils.JsonUtils; -import org.apache.eventmesh.runtime.admin.controller.HttpHandlerManager; -import org.apache.eventmesh.runtime.admin.response.Error; -import org.apache.eventmesh.runtime.admin.response.GetRegistryResponse; -import org.apache.eventmesh.runtime.common.EventHttpHandler; -import org.apache.eventmesh.runtime.constants.EventMeshConstants; -import org.apache.eventmesh.runtime.registry.Registry; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Objects; - - -import com.sun.net.httpserver.HttpExchange; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@EventHttpHandler(path = "/registry") -public class RegistryHandler extends AbstractHttpHandler { - - private final Registry eventMeshRegistry; - - public RegistryHandler(Registry eventMeshRegistry, - HttpHandlerManager httpHandlerManager) { - super(httpHandlerManager); - this.eventMeshRegistry = eventMeshRegistry; - } - - /** - * OPTION /registry - */ - void preflight(HttpExchange httpExchange) throws IOException { - httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); - httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_METHODS, "*"); - httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_AGE, EventMeshConstants.MAX_AGE); - httpExchange.sendResponseHeaders(200, 0); - OutputStream out = httpExchange.getResponseBody(); - out.close(); - } - - /** - * GET /registry Return a response that contains the list of EventMesh clusters - */ - void get(HttpExchange httpExchange) throws IOException { - OutputStream out = httpExchange.getResponseBody(); - httpExchange.getResponseHeaders().add(EventMeshConstants.CONTENT_TYPE, EventMeshConstants.APPLICATION_JSON); - httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); - - try { - List getRegistryResponseList = new ArrayList<>(); - List eventMeshDataInfos = eventMeshRegistry.findAllEventMeshInfo(); - for (EventMeshDataInfo eventMeshDataInfo : eventMeshDataInfos) { - GetRegistryResponse getRegistryResponse = new GetRegistryResponse( - eventMeshDataInfo.getEventMeshClusterName(), - eventMeshDataInfo.getEventMeshName(), - eventMeshDataInfo.getEndpoint(), - eventMeshDataInfo.getLastUpdateTimestamp(), - eventMeshDataInfo.getMetadata().toString() - ); - getRegistryResponseList.add(getRegistryResponse); - } - getRegistryResponseList.sort(Comparator.comparing(GetRegistryResponse::getEventMeshClusterName)); - - String result = JsonUtils.toJSONString(getRegistryResponseList); - httpExchange.sendResponseHeaders(200, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); - out.write(result.getBytes(Constants.DEFAULT_CHARSET)); - } catch (NullPointerException e) { - //registry not initialized, return empty list - String result = JsonUtils.toJSONString(new ArrayList<>()); - httpExchange.sendResponseHeaders(200, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); - out.write(result.getBytes(Constants.DEFAULT_CHARSET)); - } catch (Exception e) { - StringWriter writer = new StringWriter(); - PrintWriter printWriter = new PrintWriter(writer); - e.printStackTrace(printWriter); - printWriter.flush(); - String stackTrace = writer.toString(); - - Error error = new Error(e.toString(), stackTrace); - String result = JsonUtils.toJSONString(error); - httpExchange.sendResponseHeaders(500, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); - out.write(result.getBytes(Constants.DEFAULT_CHARSET)); - } finally { - if (out != null) { - try { - out.close(); - } catch (IOException e) { - log.warn("out close failed...", e); - } - } - } - } - - @Override - public void handle(HttpExchange httpExchange) throws IOException { - switch (HttpMethod.valueOf(httpExchange.getRequestMethod())) { - case OPTIONS: - preflight(httpExchange); - break; - case GET: - get(httpExchange); - break; - default: - break; - } - } -} 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 index 449c1033a4..900090e5fc 100644 --- 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 @@ -34,17 +34,34 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /clientManage/rejectAllClient} endpoint, + * which is used to reject ALL client connections belonging to the current EventMesh server node. + *

+ * CAUTION: USE WITH CARE + *

+ * It uses the {@link EventMeshTcp2Client#serverGoodby2Client} method to close the matching client connection. + * + * @see AbstractHttpHandler + */ + @Slf4j @EventHttpHandler(path = "/clientManage/rejectAllClient") public class RejectAllClientHandler extends AbstractHttpHandler { private final transient EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public RejectAllClientHandler(final EventMeshTCPServer eventMeshTCPServer, final HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); @@ -52,25 +69,26 @@ public RejectAllClientHandler(final EventMeshTCPServer eventMeshTCPServer, } /** - * remove all clients accessed by eventMesh + * Handles requests by rejecting all clients. * - * @param httpExchange - * @throws IOException + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ @Override public void handle(final HttpExchange httpExchange) throws IOException { try (OutputStream out = httpExchange.getResponseBody()) { + // Retrieve the mapping between Sessions and their corresponding client address final ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); final ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); final List successRemoteAddrs = new ArrayList<>(); try { - if (log.isInfoEnabled()) { - log.info("rejectAllClient in admin===================="); - } + log.info("rejectAllClient in admin===================="); if (!sessionMap.isEmpty()) { + // Iterate through the sessionMap and close each client connection for (final Map.Entry entry : sessionMap.entrySet()) { final InetSocketAddress addr = EventMeshTcp2Client.serverGoodby2Client( - eventMeshTCPServer, entry.getValue(), clientSessionGroupMapping); + eventMeshTCPServer.getTcpThreadPoolGroup(), entry.getValue(), clientSessionGroupMapping); + // Add the remote client address to a list of successfully rejected addresses if (addr != null) { successRemoteAddrs.add(addr); } @@ -80,7 +98,7 @@ public void handle(final HttpExchange httpExchange) throws IOException { log.error("clientManage rejectAllClient fail", e); NetUtils.sendSuccessResponseHeaders(httpExchange); out.write(String.format("rejectAllClient fail! sessionMap size {%d}, had reject {%s}, errorMsg : %s", - sessionMap.size(), NetUtils.addressToString(successRemoteAddrs), e.getMessage()) + sessionMap.size(), NetUtils.addressToString(successRemoteAddrs), e.getMessage()) .getBytes(Constants.DEFAULT_CHARSET)); return; } 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 index 77722daa81..af2d5d1328 100644 --- 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 @@ -37,31 +37,64 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /clientManage/rejectClientByIpPort} endpoint, + * which is used to reject a client connection + * that matches the provided IP address and port. + *

+ * The request must specify the client's and target EventMesh node's IP and port. + *

+ * Parameters: + *

    + *
  • client's IP: {@code ip}
  • + *
  • client's port: {@code port}
  • + *
  • target EventMesh node's IP: {@code desteventmeshIp}
  • + *
  • target EventMesh node's port: {@code desteventmeshport}
  • + *
+ * It uses the {@link EventMeshTcp2Client#serverGoodby2Client} method to close the matching client connection. + * + * @see AbstractHttpHandler + */ + @Slf4j @EventHttpHandler(path = "/clientManage/rejectClientByIpPort") public class RejectClientByIpPortHandler extends AbstractHttpHandler { private final EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public RejectClientByIpPortHandler(EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; } + /** + * Handles requests by rejecting matching clients. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { String result = ""; try (OutputStream out = httpExchange.getResponseBody()) { String queryString = httpExchange.getRequestURI().getQuery(); Map queryStringInfo = NetUtils.formData2Dic(queryString); + // Extract parameters from the query string String ip = queryStringInfo.get(EventMeshConstants.MANAGE_IP); String port = queryStringInfo.get(EventMeshConstants.MANAGE_PORT); + // Check the validity of the parameters if (StringUtils.isBlank(ip) || StringUtils.isBlank(port)) { NetUtils.sendSuccessResponseHeaders(httpExchange); result = "params illegal!"; @@ -69,15 +102,19 @@ public void handle(HttpExchange httpExchange) throws IOException { return; } log.info("rejectClientByIpPort in admin,ip:{},port:{}====================", ip, port); + // Retrieve the mapping between Sessions and their corresponding client address ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); final List successRemoteAddrs = new ArrayList(); try { if (!sessionMap.isEmpty()) { + // Iterate through the sessionMap to find matching sessions where the remote client address matches the given IP and port for (Map.Entry entry : sessionMap.entrySet()) { + // Reject client connection for each matching session found if (entry.getKey().getHostString().equals(ip) && String.valueOf(entry.getKey().getPort()).equals(port)) { - InetSocketAddress addr = EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer, + InetSocketAddress addr = EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer.getTcpThreadPoolGroup(), entry.getValue(), clientSessionGroupMapping); + // Add the remote client address to a list of successfully rejected addresses if (addr != null) { successRemoteAddrs.add(addr); } @@ -85,14 +122,13 @@ public void handle(HttpExchange httpExchange) throws IOException { } } } catch (Exception e) { - log.error("clientManage|rejectClientByIpPort|fail|ip={}|port={},errMsg={}", ip, port, e); + log.error("clientManage|rejectClientByIpPort|fail|ip={}|port={}", ip, port, e); result = String.format("rejectClientByIpPort fail! {ip=%s port=%s}, had reject {%s}, errorMsg : %s", ip, port, NetUtils.addressToString(successRemoteAddrs), e.getMessage()); NetUtils.sendSuccessResponseHeaders(httpExchange); out.write(result.getBytes(Constants.DEFAULT_CHARSET)); return; } - result = String.format("rejectClientByIpPort success! {ip=%s port=%s}, had reject {%s}", ip, port, NetUtils.addressToString(successRemoteAddrs)); NetUtils.sendSuccessResponseHeaders(httpExchange); 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 index 16e155c470..4ef5d882af 100644 --- 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 @@ -42,12 +42,35 @@ import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /clientManage/rejectClientBySubSystem} endpoint, + * which is used to reject a client connection + * that matches the provided client subsystem id in a Data Communication Network (DCN). + *

+ * The request must specify the client's subsystem id. + *

+ * Parameters: + *

    + *
  • client's subsystem id: {@code subsystem} | Example: {@code 5023}
  • + *
+ * It uses the {@link EventMeshTcp2Client#serverGoodby2Client} method to close the matching client connection. + * + * @see AbstractHttpHandler + */ + @EventHttpHandler(path = "/clientManage/rejectClientBySubSystem") @Slf4j public class RejectClientBySubSystemHandler extends AbstractHttpHandler { private final transient EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public RejectClientBySubSystemHandler(EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; @@ -65,10 +88,10 @@ private String printClients(Collection clients) { } /** - * remove c client by dcn and susysId + * Handles requests by rejecting matching clients. * - * @param httpExchange - * @throws IOException + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ @Override public void handle(HttpExchange httpExchange) throws IOException { @@ -76,8 +99,10 @@ public void handle(HttpExchange httpExchange) throws IOException { try (OutputStream out = httpExchange.getResponseBody()) { String queryString = httpExchange.getRequestURI().getQuery(); Map queryStringInfo = NetUtils.formData2Dic(queryString); + // Extract parameter from the query string String subSystem = queryStringInfo.get(EventMeshConstants.MANAGE_SUBSYSTEM); + // Check the validity of the parameters if (StringUtils.isBlank(subSystem)) { NetUtils.sendSuccessResponseHeaders(httpExchange); result = "params illegal!"; @@ -86,15 +111,19 @@ public void handle(HttpExchange httpExchange) throws IOException { } log.info("rejectClientBySubSystem in admin,subsys:{}====================", subSystem); + // Retrieve the mapping between Sessions and their corresponding client address ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); final List successRemoteAddrs = new ArrayList<>(); try { if (!sessionMap.isEmpty()) { + // Iterate through the sessionMap to find matching sessions where the client's subsystem id matches the given param for (Session session : sessionMap.values()) { + // Reject client connection for each matching session found if (session.getClient().getSubsystem().equals(subSystem)) { - InetSocketAddress addr = EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer, session, + InetSocketAddress addr = EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer.getTcpThreadPoolGroup(), session, clientSessionGroupMapping); + // Add the remote client address to a list of successfully rejected addresses if (addr != null) { successRemoteAddrs.add(addr); } @@ -102,15 +131,16 @@ public void handle(HttpExchange httpExchange) throws IOException { } } } catch (Exception e) { - log.error("clientManage|rejectClientBySubSystem|fail|subSystemId={},errMsg={}", subSystem, e); + log.error("clientManage|rejectClientBySubSystem|fail|subSystemId={}", subSystem, e); result = String.format("rejectClientBySubSystem fail! sessionMap size {%d}, had reject {%s} , {" - + - "subSystemId=%s}, errorMsg : %s", sessionMap.size(), printClients(successRemoteAddrs), + + + "subSystemId=%s}, errorMsg : %s", sessionMap.size(), printClients(successRemoteAddrs), subSystem, e.getMessage()); NetUtils.sendSuccessResponseHeaders(httpExchange); out.write(result.getBytes(Constants.DEFAULT_CHARSET)); return; } + // Serialize the successfully rejected client addresses into output stream result = String.format("rejectClientBySubSystem success! sessionMap size {%d}, had reject {%s} , {" + "subSystemId=%s}", sessionMap.size(), printClients(successRemoteAddrs), subSystem); 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 index 58168a0d4c..3bebbcd3ed 100644 --- 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 @@ -33,27 +33,46 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /clientManage/showClientBySystem} endpoint, + * which is used to display connected clients information + * under a specific subsystem by subsystem id. + *

+ * Parameters: + *

    + *
  • client's subsystem id: {@code subsystem} | Example: {@code 5023}
  • + *
+ * + * @see AbstractHttpHandler + */ + @Slf4j @EventHttpHandler(path = "/clientManage/showClientBySystem") public class ShowClientBySystemHandler extends AbstractHttpHandler { private final EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public ShowClientBySystemHandler(EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; } /** - * print clientInfo by subsys + * Handles requests by displaying clients information. * - * @param httpExchange - * @throws IOException + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ @Override public void handle(HttpExchange httpExchange) throws IOException { @@ -61,21 +80,23 @@ public void handle(HttpExchange httpExchange) throws IOException { try (OutputStream out = httpExchange.getResponseBody()) { String queryString = httpExchange.getRequestURI().getQuery(); Map queryStringInfo = NetUtils.formData2Dic(queryString); + // Extract parameter from the query string String subSystem = queryStringInfo.get(EventMeshConstants.MANAGE_SUBSYSTEM); String newLine = System.getProperty("line.separator"); - if (log.isInfoEnabled()) { - log.info("showClientBySubsys,subsys:{}", subSystem); - } + log.info("showClientBySubsys,subsys:{}", subSystem); + // Retrieve the mapping between Sessions and their corresponding client address ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); if (sessionMap != null && !sessionMap.isEmpty()) { + // Iterate through the sessionMap to find matching sessions where the client's subsystem id matches the given param for (Session session : sessionMap.values()) { + // For each matching session found, append the client's information to the result if (session.getClient().getSubsystem().equals(subSystem)) { UserAgent userAgent = session.getClient(); result.append(String.format("pid=%s | ip=%s | port=%s | path=%s | purpose=%s", - userAgent.getPid(), userAgent.getHost(), userAgent.getPort(), - userAgent.getPath(), userAgent.getPurpose())) + userAgent.getPid(), userAgent.getHost(), userAgent.getPort(), + userAgent.getPath(), userAgent.getPurpose())) .append(newLine); } } @@ -85,5 +106,4 @@ public void handle(HttpExchange httpExchange) throws IOException { } } - } 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 index cbfa2a2bf2..26b04fa4a9 100644 --- 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 @@ -32,25 +32,43 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * This handler used to print the total client info + * This class handles the HTTP requests of {@code /clientManage/showClient} endpoint. + *

+ * It is used to query information about all clients connected to the current EventMesh server node + * and to provide statistics on the number of clients in each subsystem. + * + * @see AbstractHttpHandler */ + @Slf4j @EventHttpHandler(path = "/clientManage/showClient") public class ShowClientHandler extends AbstractHttpHandler { private final EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public ShowClientHandler(EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; } + /** + * Handles requests by displaying clients information. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { StringBuilder result = new StringBuilder(); @@ -59,10 +77,12 @@ public void handle(HttpExchange httpExchange) throws IOException { log.info("showAllClient================="); ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); + // Store the subsystem and the corresponding client count. HashMap statMap = new HashMap(); Map sessionMap = clientSessionGroupMapping.getSessionMap(); if (!sessionMap.isEmpty()) { + // Iterate through each Session to count the clients in each subsystem. for (Session session : sessionMap.values()) { String key = session.getClient().getSubsystem(); if (!statMap.containsKey(key)) { @@ -72,6 +92,7 @@ public void handle(HttpExchange httpExchange) throws IOException { } } + // Generate the result with the number of clients for each subsystem. for (Map.Entry entry : statMap.entrySet()) { result.append(String.format("System=%s | ClientNum=%d", entry.getKey(), entry.getValue().intValue())).append(newLine); } 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 index 10d6001820..c1b492b53e 100644 --- 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 @@ -31,49 +31,74 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Map; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * query client subscription by topic + * This class handles the HTTP requests of {@code /clientManage/showListenClientByTopic} endpoint, + * which is used to display clients information + * subscribed to a specific topic. + *

+ * Parameters: + *

    + *
  • Message Topic: {@code topic}
  • + *
+ * + * @see AbstractHttpHandler */ + @Slf4j @EventHttpHandler(path = "/clientManage/showListenClientByTopic") public class ShowListenClientByTopicHandler extends AbstractHttpHandler { private final EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public ShowListenClientByTopicHandler(EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; } + /** + * Handles requests by displaying clients information. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { StringBuilder result = new StringBuilder(); try (OutputStream out = httpExchange.getResponseBody()) { String queryString = httpExchange.getRequestURI().getQuery(); Map queryStringInfo = NetUtils.formData2Dic(queryString); + // Extract parameter from the query string String topic = queryStringInfo.get(EventMeshConstants.MANAGE_TOPIC); String newLine = System.getProperty("line.separator"); log.info("showListeningClientByTopic,topic:{}=================", topic); + // Retrieve the mappings of client subsystem to client group ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); ConcurrentHashMap clientGroupMap = clientSessionGroupMapping.getClientGroupMap(); if (!clientGroupMap.isEmpty()) { + // Iterate through the client group to get matching sessions in the group by given topic for (ClientGroupWrapper cgw : clientGroupMap.values()) { - Set listenSessionSet = cgw.getTopic2sessionInGroupMapping().get(topic); - if (listenSessionSet != null && !listenSessionSet.isEmpty()) { + Map listenSessions = cgw.getTopic2sessionInGroupMapping().get(topic); + if (listenSessions != null && !listenSessions.isEmpty()) { result.append(String.format("group:%s", cgw.getGroup())).append(newLine); - for (Session session : listenSessionSet) { + // Iterate through the sessions to get each client information + for (Session session : listenSessions.values()) { UserAgent userAgent = session.getClient(); result.append(String.format("pid=%s | ip=%s | port=%s | path=%s | version=%s", userAgent.getPid(), userAgent - .getHost(), userAgent.getPort(), userAgent.getPath(), userAgent.getVersion())) + .getHost(), userAgent.getPort(), userAgent.getPath(), userAgent.getVersion())) .append(newLine); } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/TCPClientHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/TCPClientHandler.java index ae0a2d677c..ca89d204ca 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/TCPClientHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/TCPClientHandler.java @@ -45,29 +45,48 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * The client handler + * This class handles the {@code /client/tcp} endpoint, + * corresponding to the {@code eventmesh-dashboard} path {@code /tcp}. + *

+ * It is responsible for managing operations on TCP clients, + * including retrieving the information list of connected TCP clients + * and deleting TCP clients by disconnecting their connections based on the provided host and port. + * + * @see AbstractHttpHandler */ + @Slf4j @EventHttpHandler(path = "/client/tcp") public class TCPClientHandler extends AbstractHttpHandler { private final EventMeshTCPServer eventMeshTCPServer; + /** + * Constructs a new instance with the provided server instance and HTTP handler manager. + * + * @param eventMeshTCPServer the TCP server instance of EventMesh + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public TCPClientHandler( - EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager - ) { + EventMeshTCPServer eventMeshTCPServer, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.eventMeshTCPServer = eventMeshTCPServer; } /** - * OPTIONS /client + * Handles the OPTIONS request first for {@code /client/tcp}. + *

+ * This method adds CORS (Cross-Origin Resource Sharing) response headers to + * the {@link HttpExchange} object and sends a 200 status code. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void preflight(HttpExchange httpExchange) throws IOException { httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); @@ -80,11 +99,18 @@ void preflight(HttpExchange httpExchange) throws IOException { } /** - * DELETE /client/tcp + * Handles the DELETE request for {@code /client/tcp}. + *

+ * This method deletes a connected TCP client by disconnecting their connections + * based on the provided host and port, then returns {@code 200 OK}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void delete(HttpExchange httpExchange) throws IOException { - + try (OutputStream out = httpExchange.getResponseBody()) { + // Parse the request body string into a DeleteTCPClientRequest object String request = HttpExchangeUtils.streamToString(httpExchange.getRequestBody()); DeleteTCPClientRequest deleteTCPClientRequest = JsonUtils.parseObject(request, DeleteTCPClientRequest.class); String host = Objects.requireNonNull(deleteTCPClientRequest).getHost(); @@ -94,16 +120,18 @@ void delete(HttpExchange httpExchange) throws IOException { ConcurrentHashMap sessionMap = clientSessionGroupMapping.getSessionMap(); if (!sessionMap.isEmpty()) { for (Map.Entry entry : sessionMap.entrySet()) { + // Find the Session object that matches the host and port to be deleted if (entry.getKey().getHostString().equals(host) && entry.getKey().getPort() == port) { + // Call the serverGoodby2Client method in EventMeshTcp2Client to disconnect the client's connection EventMeshTcp2Client.serverGoodby2Client( - eventMeshTCPServer, + eventMeshTCPServer.getTcpThreadPoolGroup(), entry.getValue(), - clientSessionGroupMapping - ); + clientSessionGroupMapping); } } } + // Set the response headers and send a 200 status code empty response httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); httpExchange.sendResponseHeaders(200, 0); } catch (Exception e) { @@ -121,17 +149,24 @@ void delete(HttpExchange httpExchange) throws IOException { } /** - * GET /client/tcp Return a response that contains the list of clients + * Handles the GET request for {@code /client/tcp}. + *

+ * This method retrieves the list of connected TCP clients and returns it as a JSON response. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void list(HttpExchange httpExchange) throws IOException { try (OutputStream out = httpExchange.getResponseBody()) { + // Set the response headers httpExchange.getResponseHeaders().add(EventMeshConstants.CONTENT_TYPE, EventMeshConstants.APPLICATION_JSON); httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); - // Get the list of TCP clients + // Get the list of connected TCP clients ClientSessionGroupMapping clientSessionGroupMapping = eventMeshTCPServer.getClientSessionGroupMapping(); Map sessionMap = clientSessionGroupMapping.getSessionMap(); List getClientResponseList = new ArrayList<>(); + // Convert each Session object to GetClientResponse and add to getClientResponseList for (Session session : sessionMap.values()) { UserAgent userAgent = session.getClient(); GetClientResponse getClientResponse = new GetClientResponse( @@ -145,11 +180,11 @@ void list(HttpExchange httpExchange) throws IOException { Optional.ofNullable(userAgent.getIdc()).orElse(""), Optional.ofNullable(userAgent.getGroup()).orElse(""), Optional.ofNullable(userAgent.getPurpose()).orElse(""), - "TCP" - ); + "TCP"); getClientResponseList.add(getClientResponse); } + // Sort the getClientResponseList by host and port getClientResponseList.sort((lhs, rhs) -> { if (lhs.getHost().equals(rhs.getHost())) { return lhs.getHost().compareTo(rhs.getHost()); @@ -157,6 +192,7 @@ void list(HttpExchange httpExchange) throws IOException { return Integer.compare(rhs.getPort(), lhs.getPort()); }); + // Convert getClientResponseList to JSON and send the response String result = JsonUtils.toJSONString(getClientResponseList); httpExchange.sendResponseHeaders(200, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); out.write(result.getBytes(Constants.DEFAULT_CHARSET)); @@ -171,9 +207,20 @@ void list(HttpExchange httpExchange) throws IOException { String result = JsonUtils.toJSONString(error); httpExchange.sendResponseHeaders(500, Objects.requireNonNull(result).getBytes(Constants.DEFAULT_CHARSET).length); log.error(result, e); - } + } } + /** + * Handles the HTTP requests for {@code /client/tcp}. + *

+ * It delegates the handling to {@code preflight()}, {@code list()} or {@code delete()} methods + * based on the request method type (OPTIONS, GET or DELETE). + *

+ * This method is an implementation of {@linkplain com.sun.net.httpserver.HttpHandler#handle(HttpExchange) HttpHandler.handle()}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { switch (HttpMethod.valueOf(httpExchange.getRequestMethod())) { diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/TopicHandler.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/TopicHandler.java index aa636b1b0e..ddbaa844d1 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/TopicHandler.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/handler/TopicHandler.java @@ -37,24 +37,40 @@ import java.util.List; import java.util.Objects; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; /** - * The topic handler + * This class handles the {@code /topic} endpoint, + * corresponding to the {@code eventmesh-dashboard} path {@code /topic}, + * including the "Create Topic" and "Remove" buttons. + *

+ * It provides functionality for managing topics, including retrieving the list of topics (GET), + * creating a new topic (POST), and deleting an existing topic (DELETE). + *

+ * An instance of {@link MQAdminWrapper} is used to interact with the messaging system. + * + * @see AbstractHttpHandler + * @see MQAdminWrapper */ + @Slf4j @EventHttpHandler(path = "/topic") public class TopicHandler extends AbstractHttpHandler { private final MQAdminWrapper admin; + /** + * Constructs a new instance with the specified connector plugin type and HTTP handler manager. + * + * @param connectorPluginType The name of event storage connector plugin. + * @param httpHandlerManager httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public TopicHandler( String connectorPluginType, - HttpHandlerManager httpHandlerManager - ) { + HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); admin = new MQAdminWrapper(connectorPluginType); try { @@ -65,7 +81,13 @@ public TopicHandler( } /** - * OPTIONS /topic + * Handles the OPTIONS request first for {@code /topic}. + *

+ * This method adds CORS (Cross-Origin Resource Sharing) response headers to + * the {@link HttpExchange} object and sends a 200 status code. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void preflight(HttpExchange httpExchange) throws IOException { httpExchange.getResponseHeaders().add(EventMeshConstants.HANDLER_ORIGIN, "*"); @@ -78,7 +100,12 @@ void preflight(HttpExchange httpExchange) throws IOException { } /** - * GET /topic Return a response that contains the list of topics + * Handles the GET request for {@code /topic}. + *

+ * This method retrieves the list of topics from the {@link MQAdminWrapper} and returns it as a JSON response. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void get(HttpExchange httpExchange) throws IOException { @@ -104,7 +131,12 @@ void get(HttpExchange httpExchange) throws IOException { } /** - * POST /topic Create a topic if it doesn't exist + * Handles the POST request for {@code /topic}. + *

+ * This method creates a topic if it doesn't exist based on the request data, then returns {@code 200 OK}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void post(HttpExchange httpExchange) throws IOException { @@ -131,7 +163,12 @@ void post(HttpExchange httpExchange) throws IOException { } /** - * DELETE /topic Delete a topic if it exists + * Handles the DELETE request for {@code /topic}. + *

+ * This method deletes a topic if it exists based on the request data, then returns {@code 200 OK}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request */ void delete(HttpExchange httpExchange) throws IOException { @@ -157,6 +194,17 @@ void delete(HttpExchange httpExchange) throws IOException { } } + /** + * Handles the HTTP requests for {@code /topic}. + *

+ * It delegates the handling to {@code preflight()}, {@code get()}, {@code post()} or {@code delete()} methods + * based on the request method type (OPTIONS, GET, POST or DELETE). + *

+ * This method is an implementation of {@linkplain com.sun.net.httpserver.HttpHandler#handle(HttpExchange) HttpHandler.handle()}. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + */ @Override public void handle(HttpExchange httpExchange) throws IOException { switch (HttpMethod.valueOf(httpExchange.getRequestMethod())) { 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 index 2990cd9ba9..66b4dd572e 100644 --- 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 @@ -28,11 +28,34 @@ import java.io.IOException; import java.io.OutputStream; - import com.sun.net.httpserver.HttpExchange; import lombok.extern.slf4j.Slf4j; +/** + * This class handles the HTTP requests of {@code /webhook/updateWebHookConfig} endpoint + * and updates an existing WebHook configuration + * according to the given {@linkplain org.apache.eventmesh.webhook.api.WebHookConfig WebHookConfig}. + *

+ * The implementation of + * {@linkplain org.apache.eventmesh.webhook.api.WebHookConfigOperation#updateWebHookConfig WebHookConfigOperation} + * interface depends on the {@code eventMesh.webHook.operationMode} configuration in {@code eventmesh.properties}. + *

+ * For example, when {@code eventMesh.webHook.operationMode=file}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.FileWebHookConfigOperation#updateWebHookConfig FileWebHookConfigOperation} + * method as implementation to update the WebHook configuration in a file; + *

+ * When {@code eventMesh.webHook.operationMode=nacos}, It calls the + * {@linkplain org.apache.eventmesh.webhook.admin.NacosWebHookConfigOperation#updateWebHookConfig NacosWebHookConfigOperation} + * method as implementation to update the WebHook configuration in Nacos. + *

+ * The {@linkplain org.apache.eventmesh.webhook.receive.storage.HookConfigOperationManager#updateWebHookConfig HookConfigOperationManager} + * , another implementation of {@linkplain org.apache.eventmesh.webhook.api.WebHookConfigOperation WebHookConfigOperation} + * interface, is not used for this endpoint. + * + * @see AbstractHttpHandler + */ + @SuppressWarnings("restriction") @Slf4j @EventHttpHandler(path = "/webhook/updateWebHookConfig") @@ -40,20 +63,36 @@ public class UpdateWebHookConfigHandler extends AbstractHttpHandler { private final WebHookConfigOperation operation; + /** + * Constructs a new instance with the specified WebHook config operation and HTTP handler manager. + * + * @param operation the WebHookConfigOperation implementation used to update the WebHook config + * @param httpHandlerManager Manages the registration of {@linkplain com.sun.net.httpserver.HttpHandler HttpHandler} + * for an {@link com.sun.net.httpserver.HttpServer HttpServer}. + */ public UpdateWebHookConfigHandler(WebHookConfigOperation operation, HttpHandlerManager httpHandlerManager) { super(httpHandlerManager); this.operation = operation; } + /** + * Handles requests by updating a WebHook configuration. + * + * @param httpExchange the exchange containing the request from the client and used to send the response + * @throws IOException if an I/O error occurs while handling the request + * + * @see org.apache.eventmesh.webhook.receive.storage.HookConfigOperationManager#updateWebHookConfig(WebHookConfig) + */ @Override public void handle(HttpExchange httpExchange) throws IOException { NetUtils.sendSuccessResponseHeaders(httpExchange); - // get requestBody and resolve to WebHookConfig + // Resolve to WebHookConfig String requestBody = NetUtils.parsePostBody(httpExchange); WebHookConfig webHookConfig = JsonUtils.parseObject(requestBody, WebHookConfig.class); try (OutputStream out = httpExchange.getResponseBody()) { + // Update the existing WebHookConfig Integer code = operation.updateWebHookConfig(webHookConfig); // operating result String result = 1 == code ? "updateWebHookConfig Succeed!" : "updateWebHookConfig Failed!"; out.write(result.getBytes(Constants.DEFAULT_CHARSET)); diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/GetMetricsResponse.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/GetMetricsResponse.java index 86f4ed16ac..268aedc0f9 100755 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/GetMetricsResponse.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/GetMetricsResponse.java @@ -55,13 +55,13 @@ public class GetMetricsResponse { private int batchMsgQueueSize; private int sendMsgQueueSize; private int pushMsgQueueSize; - private int retryHTTPQueueSize; + private long retryHTTPQueueSize; private float avgBatchSendMsgCost; private float avgSendMsgCost; private float avgReplyMsgCost; // TCP Metrics - private int retryTCPQueueSize; + private long retryTCPQueueSize; private double client2eventMeshTCPTPS; private double eventMesh2mqTCPTPS; private double mq2eventMeshTCPTPS; @@ -70,7 +70,6 @@ public class GetMetricsResponse { private int allTCPConnections; private int subTopicTCPNum; - @JsonCreator public GetMetricsResponse( // HTTP Metrics @@ -103,12 +102,12 @@ public GetMetricsResponse( @JsonProperty("batchMsgQueueSize") int batchMsgQueueSize, @JsonProperty("sendMsgQueueSize") int sendMsgQueueSize, @JsonProperty("pushMsgQueueSize") int pushMsgQueueSize, - @JsonProperty("retryHTTPQueueSize") int retryHTTPQueueSize, + @JsonProperty("retryHTTPQueueSize") long retryHTTPQueueSize, @JsonProperty("avgBatchSendMsgCost") float avgBatchSendMsgCost, @JsonProperty("avgSendMsgCost") float avgSendMsgCost, @JsonProperty("avgReplyMsgCost") float avgReplyMsgCost, // TCP Metrics - @JsonProperty("retryTCPQueueSize") int retryTCPQueueSize, + @JsonProperty("retryTCPQueueSize") long retryTCPQueueSize, @JsonProperty("client2eventMeshTCPTPS") double client2eventMeshTCPTPS, @JsonProperty("eventMesh2mqTCPTPS") double eventMesh2mqTCPTPS, @JsonProperty("mq2eventMeshTCPTPS") double mq2eventMeshTCPTPS, diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/GetRegistryResponse.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/GetRegistryResponse.java index 2a2806a8b9..8416076a33 100755 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/GetRegistryResponse.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/response/GetRegistryResponse.java @@ -22,7 +22,6 @@ import lombok.Data; - @Data public class GetRegistryResponse { diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/utils/HttpExchangeUtils.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/utils/HttpExchangeUtils.java index 177b378bc6..67479c8c2f 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/utils/HttpExchangeUtils.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/admin/utils/HttpExchangeUtils.java @@ -26,17 +26,16 @@ public class HttpExchangeUtils { public static String streamToString(InputStream stream) throws IOException { - InputStreamReader isr = new InputStreamReader(stream, StandardCharsets.UTF_8); - BufferedReader bufferedReader = new BufferedReader(isr); + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { - int b; - StringBuilder buffer = new StringBuilder(); - while ((b = bufferedReader.read()) != -1) { - buffer.append((char) b); - } + StringBuilder buffer = new StringBuilder(); + int b; + + while ((b = bufferedReader.read()) != -1) { + buffer.append((char) b); + } - bufferedReader.close(); - isr.close(); - return buffer.toString(); + return buffer.toString(); + } } } 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 index d74b69a3ac..3791bd61a7 100644 --- 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 @@ -17,10 +17,9 @@ package org.apache.eventmesh.runtime.boot; -import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.common.config.CommonConfiguration; 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; @@ -28,13 +27,11 @@ import org.apache.eventmesh.common.protocol.http.common.RequestCode; import org.apache.eventmesh.common.protocol.http.header.Header; import org.apache.eventmesh.common.utils.AssertUtils; -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.util.RemotingHelper; @@ -44,11 +41,8 @@ import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.http.MethodNotSupportedException; -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; @@ -74,7 +68,6 @@ 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; @@ -97,49 +90,45 @@ 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 lombok.extern.slf4j.Slf4j; - +/** + * HTTP serves as the runtime module server for the protocol + * + */ @Slf4j public abstract class AbstractHTTPServer extends AbstractRemotingServer { - private HandlerService handlerService; - + private final transient EventMeshHTTPConfiguration eventMeshHttpConfiguration; private HTTPMetricsServer metrics; private static final DefaultHttpDataFactory DEFAULT_HTTP_DATA_FACTORY = new DefaultHttpDataFactory(false); - private final transient AtomicBoolean started = new AtomicBoolean(false); - - private final transient boolean useTLS; - - private Boolean useTrace = false; //Determine whether trace is enabled - - private final transient EventMeshHTTPConfiguration eventMeshHttpConfiguration; - - private final transient ThreadPoolExecutor asyncContextCompleteHandler = - ThreadPoolFactory.createThreadPoolExecutor(10, 10, "EventMesh-http-asyncContext"); - - private static final int MAX_CONNECTIONS = 20_000; - static { DiskAttribute.deleteOnExitTemporaryFile = false; } - protected final transient Map> - processorTable = new ConcurrentHashMap<>(64); + private final transient AtomicBoolean started = new AtomicBoolean(false); + private final transient boolean useTLS; + private Boolean useTrace = false; // Determine whether trace is enabled + private static final int MAX_CONNECTIONS = 20_000; - protected final transient Map> - eventProcessorTable = new ConcurrentHashMap<>(64); + /** + * key: request code + */ + protected final transient Map> httpRequestProcessorTable = + new ConcurrentHashMap<>(64); private HttpConnectionHandler httpConnectionHandler; + private HttpDispatcher httpDispatcher; - private HTTPHandler httpHandler; + private HandlerService handlerService; + private final transient ThreadPoolExecutor asyncContextCompleteHandler = + ThreadPoolFactory.createThreadPoolExecutor(10, 10, "EventMesh-http-asyncContext"); + + private final HTTPThreadPoolGroup httpThreadPoolGroup; public AbstractHTTPServer(final int port, final boolean useTLS, final EventMeshHTTPConfiguration eventMeshHttpConfiguration) { @@ -147,56 +136,22 @@ public AbstractHTTPServer(final int port, final boolean useTLS, this.setPort(port); this.useTLS = useTLS; this.eventMeshHttpConfiguration = eventMeshHttpConfiguration; + this.httpThreadPoolGroup = new HTTPThreadPoolGroup(eventMeshHttpConfiguration); } - - public void setUseTrace(final Boolean useTrace) { - this.useTrace = useTrace; - } - - - public Boolean getUseTrace() { - return useTrace; - } - - public void setHandlerService(final HandlerService handlerService) { - this.handlerService = handlerService; - } - - public HTTPMetricsServer getMetrics() { - return metrics; - } - - public void setMetrics(final HTTPMetricsServer metrics) { - this.metrics = metrics; - } - - public HandlerService getHandlerService() { - return handlerService; + private void initSharableHandlers() { + httpConnectionHandler = new HttpConnectionHandler(); + httpDispatcher = new HttpDispatcher(); } - public void sendError(final ChannelHandlerContext ctx, final HttpResponseStatus status) { - final FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status); - final 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 init() throws Exception { + super.init("eventMesh-http"); + httpThreadPoolGroup.initThreadPool(); } - public void sendResponse(final ChannelHandlerContext ctx, final DefaultFullHttpResponse response) { - ctx.writeAndFlush(response).addListener((ChannelFutureListener) f -> { - if (!f.isSuccess()) { - if (log.isWarnEnabled()) { - log.warn("send response to [{}] fail, will close this channel", - RemotingHelper.parseChannelRemoteAddr(f.channel())); - } - f.channel().close(); - } - }); + @Override + public CommonConfiguration getConfiguration() { + return eventMeshHttpConfiguration; } @Override @@ -204,7 +159,7 @@ public void start() throws Exception { initSharableHandlers(); - final Runnable runnable = () -> { + final Thread thread = new Thread(() -> { final ServerBootstrap bootstrap = new ServerBootstrap(); try { bootstrap.group(this.getBossGroup(), this.getIoGroup()) @@ -212,9 +167,7 @@ public void start() throws Exception { .childHandler(new HttpsServerInitializer(useTLS ? SSLContextFactory.getSslContext(eventMeshHttpConfiguration) : null)) .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE); - if (log.isInfoEnabled()) { - log.info("HTTPServer[port={}] started.", this.getPort()); - } + log.info("HTTPServer[port={}] started.", this.getPort()); bootstrap.bind(this.getPort()) .channel() @@ -227,10 +180,9 @@ public void start() throws Exception { } catch (Exception ex) { log.error("HTTPServer shutdown error!", ex); } + System.exit(-1); } - }; - - final Thread thread = new Thread(runnable, "EventMesh-http-server"); + }, "EventMesh-http-server"); thread.setDaemon(true); thread.start(); started.compareAndSet(false, true); @@ -239,23 +191,18 @@ public void start() throws Exception { @Override public void shutdown() throws Exception { super.shutdown(); + httpThreadPoolGroup.shutdownThreadPool(); started.compareAndSet(true, false); } - public void registerProcessor(final Integer requestCode, final HttpRequestProcessor processor, - final ThreadPoolExecutor executor) { + /** + * Registers the processors required by the runtime module + */ + public void registerProcessor(final Integer requestCode, final HttpRequestProcessor processor, final ThreadPoolExecutor executor) { AssertUtils.notNull(requestCode, "requestCode can't be null"); AssertUtils.notNull(processor, "processor can't be null"); AssertUtils.notNull(executor, "executor can't be null"); - this.processorTable.put(requestCode.toString(), new Pair<>(processor, executor)); - } - - public void registerProcessor(final String requestURI, final EventProcessor processor, - final ThreadPoolExecutor executor) { - AssertUtils.notNull(requestURI, "requestURI can't be null"); - AssertUtils.notNull(processor, "processor can't be null"); - AssertUtils.notNull(executor, "executor can't be null"); - this.eventProcessorTable.put(requestURI, new Pair<>(processor, executor)); + this.httpRequestProcessorTable.put(requestCode.toString(), new Pair<>(processor, executor)); } /** @@ -284,23 +231,24 @@ private HttpResponseStatus validateHttpRequest(final HttpRequest httpRequest) { 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(final ChannelHandlerContext ctx, final HttpRequest httpRequest) { - final long startTime = System.currentTimeMillis(); - final HttpHeaders requestHeaders = httpRequest.headers(); + public void sendError(final ChannelHandlerContext ctx, final HttpResponseStatus status) { + final FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status); + final 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); - requestHeaders.set(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, startTime); - if (StringUtils.isBlank(requestHeaders.get(ProtocolKey.VERSION))) { - requestHeaders.set(ProtocolKey.VERSION, ProtocolVersion.V1.getVersion()); - } - requestHeaders.set(ProtocolKey.ClientInstanceKey.IP, - RemotingHelper.parseChannelRemoteAddr(ctx.channel())); - requestHeaders.set(EventMeshConstants.REQ_SEND_EVENTMESH_IP, eventMeshHttpConfiguration.getEventMeshServerIp()); + ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); + } + + public void sendResponse(final ChannelHandlerContext ctx, final DefaultFullHttpResponse response) { + ctx.writeAndFlush(response).addListener((ChannelFutureListener) f -> { + if (!f.isSuccess()) { + log.warn("send response to [{}] fail, will close this channel", RemotingHelper.parseChannelRemoteAddr(f.channel())); + f.channel().close(); + } + }); } /** @@ -318,31 +266,34 @@ private Map parseHttpRequestBody(final HttpRequest httpRequest) .parameters() .forEach((key, value) -> httpRequestBody.put(key, value.get(0))); } else if (HttpMethod.POST.equals(httpRequest.method())) { - final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(DEFAULT_HTTP_DATA_FACTORY, httpRequest); - for (final InterfaceHttpData parm : decoder.getBodyHttpDatas()) { - if (InterfaceHttpData.HttpDataType.Attribute == parm.getHttpDataType()) { - final Attribute data = (Attribute) parm; - httpRequestBody.put(data.getName(), data.getValue()); - } - } - decoder.destroy(); + decodeHttpRequestBody(httpRequest, httpRequestBody); } metrics.getSummaryMetrics().recordDecodeTimeCost(System.currentTimeMillis() - bodyDecodeStart); return httpRequestBody; } + private void decodeHttpRequestBody(HttpRequest httpRequest, Map httpRequestBody) throws IOException { + final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(DEFAULT_HTTP_DATA_FACTORY, httpRequest); + for (final InterfaceHttpData param : decoder.getBodyHttpDatas()) { + if (InterfaceHttpData.HttpDataType.Attribute == param.getHttpDataType()) { + final Attribute data = (Attribute) param; + httpRequestBody.put(data.getName(), data.getValue()); + } + } + decoder.destroy(); + } + @Sharable - private class HTTPHandler extends ChannelInboundHandlerAdapter { + private class HttpDispatcher extends ChannelInboundHandlerAdapter { /** * Is called for each message of type {@link HttpRequest}. * * @param ctx the {@link ChannelHandlerContext} which this {@link ChannelInboundHandlerAdapter} belongs to * @param msg the message to handle - * @throws Exception is thrown if an error occurred */ @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + public void channelRead(ChannelHandlerContext ctx, Object msg) { if (!(msg instanceof HttpRequest)) { return; } @@ -357,7 +308,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception try { Span span = null; - preProcessHttpRequestHeader(ctx, httpRequest); + injectHttpRequestHeader(ctx, httpRequest); final Map headerMap = Utils.parseHttpHeader(httpRequest); final HttpResponseStatus errorStatus = validateHttpRequest(httpRequest); @@ -370,156 +321,86 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception } metrics.getSummaryMetrics().recordHTTPRequest(); - boolean useRequestURI = false; - for (final String processURI : eventProcessorTable.keySet()) { - if (httpRequest.uri().startsWith(processURI)) { - useRequestURI = true; - break; - } - } + // process http + final HttpCommand requestCommand = new HttpCommand(); + final Map bodyMap = parseHttpRequestBody(httpRequest); - if (useRequestURI) { - if (useTrace) { - span.setAttribute(SemanticAttributes.HTTP_METHOD, - httpRequest.method() == null ? "" : httpRequest.method().name()); - span.setAttribute(SemanticAttributes.HTTP_FLAVOR, - httpRequest.protocolVersion() == null ? "" : httpRequest.protocolVersion().protocolName()); - span.setAttribute(SemanticAttributes.HTTP_URL, - httpRequest.uri()); - } - final HttpEventWrapper httpEventWrapper = parseHttpRequest(httpRequest); - - final AsyncContext asyncContext = - new AsyncContext<>(httpEventWrapper, null, asyncContextCompleteHandler); - processHttpRequest(ctx, asyncContext); - - } else { - final HttpCommand requestCommand = new HttpCommand(); - final Map bodyMap = parseHttpRequestBody(httpRequest); - - final String requestCode = HttpMethod.POST.equals(httpRequest.method()) - ? httpRequest.headers().get(ProtocolKey.REQUEST_CODE) - : MapUtils.getString(bodyMap, StringUtils.lowerCase(ProtocolKey.REQUEST_CODE), ""); - - requestCommand.setHttpMethod(httpRequest.method().name()); - requestCommand.setHttpVersion(httpRequest.protocolVersion() == null ? "" - : 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; - } + final String requestCode = HttpMethod.POST.equals(httpRequest.method()) + ? httpRequest.headers().get(ProtocolKey.REQUEST_CODE) + : MapUtils.getString(bodyMap, StringUtils.lowerCase(ProtocolKey.REQUEST_CODE), ""); - 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; - } + requestCommand.setHttpMethod(httpRequest.method().name()); + requestCommand.setHttpVersion(httpRequest.protocolVersion() == null ? "" + : httpRequest.protocolVersion().protocolName()); + requestCommand.setRequestCode(requestCode); - if (log.isDebugEnabled()) { - log.debug("{}", requestCommand); - } + HttpCommand responseCommand = null; + + if (StringUtils.isBlank(requestCode) + || !httpRequestProcessorTable.containsKey(requestCode) + || !RequestCode.contains(Integer.valueOf(requestCode))) { + responseCommand = + requestCommand.createHttpCommandResponse(EventMeshRetCode.EVENTMESH_REQUESTCODE_INVALID); + sendResponse(ctx, responseCommand.httpResponse(HttpResponseStatus.BAD_REQUEST)); - final AsyncContext asyncContext = - new AsyncContext<>(requestCommand, responseCommand, asyncContextCompleteHandler); - processEventMeshRequest(ctx, asyncContext); + 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(HttpResponseStatus.INTERNAL_SERVER_ERROR)); + + span = TraceUtils.prepareServerSpan(headerMap, + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + TraceUtils.finishSpanWithException(span, headerMap, + EventMeshRetCode.EVENTMESH_RUNTIME_ERR.getErrMsg(), e); + return; + } + + log.debug("{}", requestCommand); + + final AsyncContext asyncContext = + new AsyncContext<>(requestCommand, responseCommand, asyncContextCompleteHandler); + processHttpCommandRequest(ctx, asyncContext); + } catch (Exception ex) { log.error("AbstractHTTPServer.HTTPHandler.channelRead error", ex); + sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR); } finally { ReferenceCountUtil.release(httpRequest); } } - public void processHttpRequest(final ChannelHandlerContext ctx, - final AsyncContext asyncContext) { - final HttpEventWrapper requestWrapper = asyncContext.getRequest(); - final String requestURI = requestWrapper.getRequestURI(); - String processorKey = "/"; - for (final String eventProcessorKey : eventProcessorTable.keySet()) { - if (requestURI.startsWith(eventProcessorKey)) { - processorKey = eventProcessorKey; - break; - } - } - - final Pair choosed = eventProcessorTable.get(processorKey); - try { - choosed.getObject2().submit(() -> { - try { - final EventProcessor processor = choosed.getObject1(); - if (processor.rejectRequest()) { - final HttpEventWrapper responseWrapper = - requestWrapper.createHttpResponse(EventMeshRetCode.EVENTMESH_REJECT_BY_PROCESSOR_ERROR); - - asyncContext.onComplete(responseWrapper); - - if (asyncContext.isComplete()) { - if (log.isDebugEnabled()) { - log.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 (log.isDebugEnabled()) { - log.debug("{}", asyncContext.getResponse()); - } + /** + * Inject ip and protocol version, if the protocol version is empty, set default to {@link ProtocolVersion#V1}. + * + * @param ctx + * @param httpRequest + */ + private void injectHttpRequestHeader(final ChannelHandlerContext ctx, final HttpRequest httpRequest) { + final long startTime = System.currentTimeMillis(); + final HttpHeaders requestHeaders = httpRequest.headers(); - sendResponse(ctx, asyncContext.getResponse().httpResponse()); - } catch (Exception e) { - log.error("process error", e); - } - }); - } catch (RejectedExecutionException re) { - final 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) { - log.error("sendResponse error", e); - } + requestHeaders.set(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, startTime); + if (StringUtils.isBlank(requestHeaders.get(ProtocolKey.VERSION))) { + requestHeaders.set(ProtocolKey.VERSION, ProtocolVersion.V1.getVersion()); } + requestHeaders.set(ProtocolKey.ClientInstanceKey.IP.getKey(), + RemotingHelper.parseChannelRemoteAddr(ctx.channel())); + requestHeaders.set(EventMeshConstants.REQ_SEND_EVENTMESH_IP, eventMeshHttpConfiguration.getEventMeshServerIp()); } - public void processEventMeshRequest(final ChannelHandlerContext ctx, - final AsyncContext asyncContext) { + private void processHttpCommandRequest(final ChannelHandlerContext ctx, final AsyncContext asyncContext) { final HttpCommand request = asyncContext.getRequest(); - final Pair choosed = processorTable.get(request.getRequestCode()); + final Pair choosed = httpRequestProcessorTable.get(request.getRequestCode()); try { choosed.getObject2().submit(() -> { try { @@ -531,13 +412,11 @@ public void processEventMeshRequest(final ChannelHandlerContext ctx, if (asyncContext.isComplete()) { sendResponse(ctx, responseCommand.httpResponse()); - if (log.isDebugEnabled()) { - log.debug("{}", asyncContext.getResponse()); - } + log.debug("{}", asyncContext.getResponse()); final Map traceMap = asyncContext.getRequest().getHeader().toMap(); TraceUtils.finishSpanWithException(TraceUtils.prepareServerSpan(traceMap, - EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, - false), + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, + false), traceMap, EventMeshRetCode.EVENTMESH_REJECT_BY_PROCESSOR_ERROR.getErrMsg(), null); } @@ -553,9 +432,7 @@ public void processEventMeshRequest(final ChannelHandlerContext ctx, metrics.getSummaryMetrics() .recordHTTPReqResTimeCost(System.currentTimeMillis() - request.getReqTime()); - if (log.isDebugEnabled()) { - log.debug("{}", asyncContext.getResponse()); - } + log.debug("{}", asyncContext.getResponse()); sendResponse(ctx, asyncContext.getResponse().httpResponse()); @@ -601,67 +478,6 @@ public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cau ctx.close(); } } - - Map extractFromRequest(final HttpRequest httpRequest) { - return new HashMap<>(); - } - } - - private HttpEventWrapper parseHttpRequest(final HttpRequest httpRequest) throws IOException, MethodNotSupportedException { - final HttpEventWrapper httpEventWrapper = new HttpEventWrapper(); - httpEventWrapper.setHttpMethod(httpRequest.method().name()); - httpEventWrapper.setHttpVersion(httpRequest.protocolVersion().protocolName()); - httpEventWrapper.setRequestURI(httpRequest.uri()); - - //parse http header - for (final String key : httpRequest.headers().names()) { - httpEventWrapper.getHeaderMap().put(key, httpRequest.headers().get(key)); - } - - final long bodyDecodeStart = System.currentTimeMillis(); - - final FullHttpRequest fullHttpRequest = (FullHttpRequest) httpRequest; - final Map bodyMap = new HashMap<>(); - - if (HttpMethod.GET.equals(fullHttpRequest.method())) { - new QueryStringDecoder(fullHttpRequest.uri()).parameters().forEach((key, value) -> bodyMap.put(key, value.get(0))); - } else if (HttpMethod.POST.equals(fullHttpRequest.method())) { - if (StringUtils.contains(httpRequest.headers().get("Content-Type"), - ContentType.APPLICATION_JSON.getMimeType())) { - final int length = fullHttpRequest.content().readableBytes(); - if (length > 0) { - final byte[] body = new byte[length]; - fullHttpRequest.content().readBytes(body); - bodyMap.putAll(Objects.requireNonNull(JsonUtils.parseTypeReferenceObject(new String(body, Constants.DEFAULT_CHARSET), - new TypeReference>() { - }))); - } - } else { - final HttpPostRequestDecoder decoder = - new HttpPostRequestDecoder(DEFAULT_HTTP_DATA_FACTORY, httpRequest); - for (final InterfaceHttpData parm : decoder.getBodyHttpDatas()) { - if (InterfaceHttpData.HttpDataType.Attribute == parm.getHttpDataType()) { - final Attribute data = (Attribute) parm; - bodyMap.put(data.getName(), data.getValue()); - } - } - decoder.destroy(); - } - - } else { - throw new MethodNotSupportedException("UnSupported Method " + fullHttpRequest.method()); - } - - httpEventWrapper.setBody(Objects.requireNonNull(JsonUtils.toJSONString(bodyMap)).getBytes(StandardCharsets.UTF_8)); - - metrics.getSummaryMetrics().recordDecodeTimeCost(System.currentTimeMillis() - bodyDecodeStart); - - return httpEventWrapper; - } - - private void initSharableHandlers() { - httpConnectionHandler = new HttpConnectionHandler(); - httpHandler = new HTTPHandler(); } @Sharable @@ -672,10 +488,8 @@ private class HttpConnectionHandler extends ChannelDuplexHandler { @Override public void channelActive(final ChannelHandlerContext ctx) throws Exception { if (connections.incrementAndGet() > MAX_CONNECTIONS) { - if (log.isWarnEnabled()) { - log.warn("client|http|channelActive|remoteAddress={}|msg=too many client({}) connect this eventMesh server", - RemotingHelper.parseChannelRemoteAddr(ctx.channel()), MAX_CONNECTIONS); - } + log.warn("client|http|channelActive|remoteAddress={}|msg=too many client({}) connect this eventMesh server", + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), MAX_CONNECTIONS); ctx.close(); return; } @@ -694,10 +508,7 @@ public void userEventTriggered(final ChannelHandlerContext ctx, final Object evt final IdleStateEvent event = (IdleStateEvent) evt; if (event.state().equals(IdleState.ALL_IDLE)) { final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - if (log.isInfoEnabled()) { - log.info("client|http|userEventTriggered|remoteAddress={}|msg={}", - remoteAddress, evt.getClass().getName()); - } + log.info("client|http|userEventTriggered|remoteAddress={}|msg={}", remoteAddress, evt.getClass().getName()); ctx.close(); } } @@ -729,8 +540,35 @@ protected void initChannel(final SocketChannel channel) { new HttpResponseEncoder(), httpConnectionHandler, new HttpObjectAggregator(Integer.MAX_VALUE), - httpHandler); + httpDispatcher); } } + public void setUseTrace(final Boolean useTrace) { + this.useTrace = useTrace; + } + + public Boolean getUseTrace() { + return useTrace; + } + + public HTTPMetricsServer getMetrics() { + return metrics; + } + + public void setMetrics(final HTTPMetricsServer metrics) { + this.metrics = metrics; + } + + public HTTPThreadPoolGroup getHttpThreadPoolGroup() { + return httpThreadPoolGroup; + } + + public HandlerService getHandlerService() { + return handlerService; + } + + public void setHandlerService(HandlerService handlerService) { + this.handlerService = handlerService; + } } 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 index a73e28ebcc..dd9a784350 100644 --- 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 @@ -20,6 +20,7 @@ import org.apache.eventmesh.common.EventMeshThreadFactory; import org.apache.eventmesh.common.utils.SystemUtils; import org.apache.eventmesh.common.utils.ThreadUtils; +import org.apache.eventmesh.runtime.core.protocol.producer.ProducerManager; import java.util.concurrent.TimeUnit; @@ -29,56 +30,24 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.util.concurrent.EventExecutorGroup; - import lombok.extern.slf4j.Slf4j; +/** + * The most basic server + */ @Slf4j -public abstract class AbstractRemotingServer { +public abstract class AbstractRemotingServer implements RemotingServer { + private static final int MAX_THREADS = Runtime.getRuntime().availableProcessors(); private static final int DEFAULT_SLEEP_SECONDS = 30; private EventLoopGroup bossGroup; - private EventLoopGroup ioGroup; - private EventExecutorGroup workerGroup; + protected ProducerManager producerManager; private int port; - private static final int MAX_THREADS = Runtime.getRuntime().availableProcessors(); - - public EventLoopGroup getBossGroup() { - return bossGroup; - } - - public EventLoopGroup getIoGroup() { - return ioGroup; - } - - public EventExecutorGroup getWorkerGroup() { - return workerGroup; - } - - public int getPort() { - return port; - } - - public void setBossGroup(final EventLoopGroup bossGroup) { - this.bossGroup = bossGroup; - } - - public void setIoGroup(final EventLoopGroup ioGroup) { - this.ioGroup = ioGroup; - } - - public void setWorkerGroup(final EventExecutorGroup workerGroup) { - this.workerGroup = workerGroup; - } - - public void setPort(final int port) { - this.port = port; - } - private void buildBossGroup(final String threadPrefix) { if (useEpoll()) { bossGroup = new EpollEventLoopGroup(1, new EventMeshThreadFactory(threadPrefix + "NettyEpoll-Boss", true)); @@ -100,34 +69,44 @@ private void buildWorkerGroup(final String threadPrefix) { workerGroup = new NioEventLoopGroup(MAX_THREADS, new EventMeshThreadFactory(threadPrefix + "-worker")); } + protected void initProducerManager() throws Exception { + producerManager = new ProducerManager(this); + producerManager.init(); + } + + public ProducerManager getProducerManager() { + return producerManager; + } + public void init(final String threadPrefix) throws Exception { buildBossGroup(threadPrefix); buildIOGroup(threadPrefix); buildWorkerGroup(threadPrefix); + initProducerManager(); + } + + public void start() throws Exception { + producerManager.start(); } public void shutdown() throws Exception { if (bossGroup != null) { bossGroup.shutdownGracefully(); - if (log.isInfoEnabled()) { - log.info("shutdown bossGroup"); - } + log.info("shutdown bossGroup"); } + producerManager.shutdown(); ThreadUtils.randomPause(TimeUnit.SECONDS.toMillis(DEFAULT_SLEEP_SECONDS)); if (ioGroup != null) { ioGroup.shutdownGracefully(); - if (log.isInfoEnabled()) { - log.info("shutdown ioGroup"); - } + log.info("shutdown ioGroup"); } if (workerGroup != null) { workerGroup.shutdownGracefully(); - if (log.isInfoEnabled()) { - log.info("shutdown workerGroup"); - } + + log.info("shutdown workerGroup"); } } @@ -135,5 +114,35 @@ protected boolean useEpoll() { return SystemUtils.isLinuxPlatform() && Epoll.isAvailable(); } - public abstract void start() throws Exception; + public EventLoopGroup getBossGroup() { + return bossGroup; + } + + public void setBossGroup(final EventLoopGroup bossGroup) { + this.bossGroup = bossGroup; + } + + public EventLoopGroup getIoGroup() { + return ioGroup; + } + + public void setIoGroup(final EventLoopGroup ioGroup) { + this.ioGroup = ioGroup; + } + + public EventExecutorGroup getWorkerGroup() { + return workerGroup; + } + + public void setWorkerGroup(final EventExecutorGroup workerGroup) { + this.workerGroup = workerGroup; + } + + public int getPort() { + return port; + } + + public void setPort(final int port) { + this.port = port; + } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/AbstractTCPServer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/AbstractTCPServer.java new file mode 100644 index 0000000000..8e2739c184 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/AbstractTCPServer.java @@ -0,0 +1,491 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.CommonConfiguration; +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.common.protocol.tcp.UserAgent; +import org.apache.eventmesh.common.protocol.tcp.codec.Codec; +import org.apache.eventmesh.common.utils.AssertUtils; +import org.apache.eventmesh.runtime.common.Pair; +import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; +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.processor.TcpProcessor; +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.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.TraceUtils; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.channel.AdaptiveRecvByteBufAllocator; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandler.Sharable; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelOption; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.epoll.EpollServerSocketChannel; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; +import io.netty.handler.timeout.IdleStateHandler; +import io.netty.handler.traffic.ChannelTrafficShapingHandler; +import io.netty.handler.traffic.GlobalTrafficShapingHandler; +import io.opentelemetry.api.trace.Span; + +import lombok.extern.slf4j.Slf4j; + +/** + * TCP serves as the runtime module server for the protocol + * + */ +@Slf4j +public class AbstractTCPServer extends AbstractRemotingServer { + + private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); + + private final EventMeshTCPConfiguration eventMeshTCPConfiguration; + private ClientSessionGroupMapping clientSessionGroupMapping; + + private EventMeshTcpMonitor eventMeshTcpMonitor; + + private transient GlobalTrafficShapingHandler globalTrafficShapingHandler; + private TcpConnectionHandler tcpConnectionHandler; + private TcpDispatcher tcpDispatcher; + + private final Map> tcpRequestProcessorTable = + new ConcurrentHashMap<>(64); + + private final transient AtomicBoolean started = new AtomicBoolean(false); + + private final TCPThreadPoolGroup tcpThreadPoolGroup; + + public AbstractTCPServer(EventMeshTCPConfiguration eventMeshTCPConfiguration) { + this.eventMeshTCPConfiguration = eventMeshTCPConfiguration; + this.tcpThreadPoolGroup = new TCPThreadPoolGroup(eventMeshTCPConfiguration); + } + + private void initSharableHandlers() { + tcpConnectionHandler = new TcpConnectionHandler(); + tcpDispatcher = new TcpDispatcher(); + } + + public void init() throws Exception { + super.init("eventMesh-tcp"); + tcpThreadPoolGroup.initThreadPool(); + } + + @Override + public CommonConfiguration getConfiguration() { + return eventMeshTCPConfiguration; + } + + @Override + public void start() throws Exception { + initSharableHandlers(); + + Thread thread = new Thread(() -> { + final ServerBootstrap bootstrap = new ServerBootstrap(); + + bootstrap.group(this.getBossGroup(), this.getIoGroup()) + .channel(useEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class) + .option(ChannelOption.SO_BACKLOG, 128) + .option(ChannelOption.SO_REUSEADDR, true) + .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) + .childOption(ChannelOption.SO_KEEPALIVE, false) + .childOption(ChannelOption.SO_LINGER, 0) + .childOption(ChannelOption.SO_TIMEOUT, 600_000) + .childOption(ChannelOption.TCP_NODELAY, true) + .childOption(ChannelOption.SO_SNDBUF, 65_535 * 4) + .childOption(ChannelOption.SO_RCVBUF, 65_535 * 4) + .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(2_048, 4_096, 65_536)) + .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) + .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) + .childHandler(new TcpServerInitializer()); + + try { + int port = eventMeshTCPConfiguration.getEventMeshTcpServerPort(); + ChannelFuture f = bootstrap.bind(port).sync(); + log.info("EventMeshTCPServer[port={}] started.....", port); + f.channel().closeFuture().sync(); + } catch (Exception e) { + log.error("EventMeshTCPServer RemotingServer Start Err!", e); + try { + shutdown(); + } catch (Exception ex) { + log.error("EventMeshTCPServer RemotingServer shutdown Err!", ex); + } + System.exit(-1); + } + }, "eventMesh-tcp-server"); + thread.start(); + + started.compareAndSet(false, true); + + } + + @Override + public void shutdown() throws Exception { + super.shutdown(); + tcpThreadPoolGroup.shutdownThreadPool(); + globalTrafficShapingHandler.release(); + started.compareAndSet(true, false); + } + + /** + * Registers the processors required by the runtime module + * + */ + public void registerProcessor(final Command command, final TcpProcessor processor, + final ThreadPoolExecutor executor) { + AssertUtils.notNull(command, "command can't be null"); + AssertUtils.notNull(processor, "processor can't be null"); + AssertUtils.notNull(executor, "executor can't be null"); + this.tcpRequestProcessorTable.put(command, new Pair<>(processor, executor)); + } + + private class TcpServerInitializer extends ChannelInitializer { + + @Override + protected void initChannel(SocketChannel ch) { + globalTrafficShapingHandler = newGTSHandler(tcpThreadPoolGroup.getScheduler(), eventMeshTCPConfiguration.getCtc().getReadLimit()); + ch.pipeline() + .addLast(getWorkerGroup(), new Codec.Encoder()) + .addLast(getWorkerGroup(), new Codec.Decoder()) + .addLast(getWorkerGroup(), "global-traffic-shaping", globalTrafficShapingHandler) + .addLast(getWorkerGroup(), "channel-traffic-shaping", newCTSHandler(eventMeshTCPConfiguration.getCtc().getReadLimit())) + .addLast(getWorkerGroup(), tcpConnectionHandler) + .addLast(getWorkerGroup(), + new IdleStateHandler( + eventMeshTCPConfiguration.getEventMeshTcpIdleReadSeconds(), + eventMeshTCPConfiguration.getEventMeshTcpIdleWriteSeconds(), + eventMeshTCPConfiguration.getEventMeshTcpIdleAllSeconds()), + new TcpDispatcher()); + } + + private GlobalTrafficShapingHandler newGTSHandler(final ScheduledExecutorService executor, final long readLimit) { + GlobalTrafficShapingHandler handler = new GlobalTrafficShapingHandler(executor, 0, readLimit) { + + @Override + protected long calculateSize(final Object msg) { + return 1; + } + }; + handler.setMaxTimeWait(1_000); + return handler; + } + + private ChannelTrafficShapingHandler newCTSHandler(final long readLimit) { + ChannelTrafficShapingHandler handler = new ChannelTrafficShapingHandler(0, readLimit) { + + @Override + protected long calculateSize(final Object msg) { + return 1; + } + }; + handler.setMaxTimeWait(3_000); + return handler; + } + + } + + @Sharable + private class TcpDispatcher extends SimpleChannelInboundHandler { + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Package pkg) throws Exception { + long startTime = System.currentTimeMillis(); + validateMsg(pkg); + + eventMeshTcpMonitor.getTcpSummaryMetrics().getClient2eventMeshMsgNum().incrementAndGet(); + + Command cmd = pkg.getHeader().getCmd(); + try { + if (isNeedTrace(cmd)) { + pkg.getHeader().getProperties() + .put(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, startTime); + pkg.getHeader().getProperties().put(EventMeshConstants.REQ_SEND_EVENTMESH_IP, + eventMeshTCPConfiguration.getEventMeshServerIp()); + Session session = clientSessionGroupMapping.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 (Command.HELLO_REQUEST == cmd || Command.RECOMMEND_REQUEST == cmd) { + MESSAGE_LOGGER.info("pkg|c2eventMesh|cmd={}|pkg={}", cmd, pkg); + processTcpCommandRequest(pkg, ctx, startTime, cmd); + return; + } + + if (clientSessionGroupMapping.getSession(ctx) == null) { + MESSAGE_LOGGER.info("pkg|c2eventMesh|cmd={}|pkg={}, no session is found", cmd, pkg); + throw new Exception("no session is found"); + } + + logMessageFlow(ctx, pkg, cmd); + + if (clientSessionGroupMapping.getSession(ctx) + .getSessionState() == SessionState.CLOSED) { + throw new Exception( + "this eventMesh tcp session will be closed, may be reboot or version change!"); + } + + processTcpCommandRequest(pkg, ctx, startTime, cmd); + } catch (Exception e) { + log.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 void processTcpCommandRequest(final Package pkg, final ChannelHandlerContext ctx, + final long startTime, final Command cmd) { + + Pair pair = tcpRequestProcessorTable.get(cmd); + pair.getObject2().submit(() -> { + TcpProcessor processor = pair.getObject1(); + + processor.process(pkg, ctx, startTime); + + }); + } + + private boolean isNeedTrace(Command cmd) { + return eventMeshTCPConfiguration.isEventMeshServerTraceEnable() + && (Command.REQUEST_TO_SERVER == cmd + || Command.ASYNC_MESSAGE_TO_SERVER == cmd + || Command.BROADCAST_MESSAGE_TO_SERVER == cmd); + } + + 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) { + log.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 (!MESSAGE_LOGGER.isInfoEnabled()) { + return; + } + + if (pkg.getBody() instanceof EventMeshMessage) { + MESSAGE_LOGGER.info("pkg|c2eventMesh|cmd={}|Msg={}|user={}", cmd, + EventMeshUtil.printMqMessage((EventMeshMessage) pkg.getBody()), + clientSessionGroupMapping.getSession(ctx).getClient()); + } else { + MESSAGE_LOGGER.info("pkg|c2eventMesh|cmd={}|pkg={}|user={}", cmd, pkg, + clientSessionGroupMapping.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) { + log.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) { + log.error("the incoming message does not have a command type|pkg={}", pkg); + throw new Exception("the incoming message does not have a command type."); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { + Session session = clientSessionGroupMapping.getSession(ctx); + UserAgent client = session == null ? null : session.getClient(); + log.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(tcpThreadPoolGroup, session, errMsg, OPStatus.FAIL.getCode(), + clientSessionGroupMapping); + } else { + EventMeshTcp2Client.goodBye2Client(ctx, errMsg, clientSessionGroupMapping, eventMeshTcpMonitor); + } + } + + } + + @Sharable + public class TcpConnectionHandler extends ChannelDuplexHandler { + + private final AtomicInteger connections = new AtomicInteger(0); + + @Override + public void channelRegistered(ChannelHandlerContext ctx) throws Exception { + final String remoteAddress = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + log.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()); + log.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()); + log.info("client|tcp|channelActive|remoteAddress={}|msg={}", remoteAddress, ""); + + if (connections.incrementAndGet() > eventMeshTCPConfiguration.getEventMeshTcpClientMaxNum()) { + log.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()); + log.info("client|tcp|channelInactive|remoteAddress={}|msg={}", remoteAddress, ""); + clientSessionGroupMapping.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()); + log.info("client|tcp|userEventTriggered|remoteAddress={}|msg={}", remoteAddress, evt.getClass().getName()); + clientSessionGroupMapping.closeSession(ctx); + } + } + + ctx.fireUserEventTriggered(evt); + } + + public int getConnectionCount() { + return this.connections.get(); + } + } + + public TcpConnectionHandler getTcpConnectionHandler() { + return tcpConnectionHandler; + } + + public EventMeshTcpMonitor getEventMeshTcpMonitor() { + return eventMeshTcpMonitor; + } + + public void setEventMeshTcpMonitor(EventMeshTcpMonitor eventMeshTcpMonitor) { + this.eventMeshTcpMonitor = eventMeshTcpMonitor; + } + + public TcpDispatcher getTcpDispatcher() { + return tcpDispatcher; + } + + public void setTcpDispatcher(TcpDispatcher tcpDispatcher) { + this.tcpDispatcher = tcpDispatcher; + } + + public TCPThreadPoolGroup getTcpThreadPoolGroup() { + return tcpThreadPoolGroup; + } + + public ClientSessionGroupMapping getClientSessionGroupMapping() { + return clientSessionGroupMapping; + } + + public void setClientSessionGroupMapping(ClientSessionGroupMapping clientSessionGroupMapping) { + this.clientSessionGroupMapping = clientSessionGroupMapping; + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshGrpcBootstrap.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshGrpcBootstrap.java index 66cfa2a176..dc218084b1 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshGrpcBootstrap.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshGrpcBootstrap.java @@ -17,6 +17,8 @@ package org.apache.eventmesh.runtime.boot; +import static org.apache.eventmesh.common.Constants.GRPC; + import org.apache.eventmesh.common.config.ConfigService; import org.apache.eventmesh.common.utils.ConfigurationContextUtil; import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; @@ -34,7 +36,7 @@ public EventMeshGrpcBootstrap(final EventMeshServer eventMeshServer) { ConfigService configService = ConfigService.getInstance(); this.eventMeshGrpcConfiguration = configService.buildConfigInstance(EventMeshGrpcConfiguration.class); - ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.GRPC, eventMeshGrpcConfiguration); + ConfigurationContextUtil.putIfAbsent(GRPC, eventMeshGrpcConfiguration); } @Override 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 index 79f61a86e8..58832d1d39 100644 --- 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 @@ -17,11 +17,13 @@ package org.apache.eventmesh.runtime.boot; -import org.apache.eventmesh.api.registry.dto.EventMeshRegisterInfo; -import org.apache.eventmesh.api.registry.dto.EventMeshUnRegisterInfo; +import static org.apache.eventmesh.common.Constants.GRPC; + +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.common.config.CommonConfiguration; 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.metrics.api.MetricsPluginFactory; import org.apache.eventmesh.metrics.api.MetricsRegistry; @@ -29,20 +31,19 @@ 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.core.protocol.grpc.service.PublisherService; +import org.apache.eventmesh.runtime.meta.MetaStorage; import org.apache.eventmesh.runtime.metrics.grpc.EventMeshGrpcMonitor; -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.ArrayList; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Optional; import java.util.concurrent.BlockingQueue; @@ -59,7 +60,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class EventMeshGrpcServer { +public class EventMeshGrpcServer extends AbstractRemotingServer { private final EventMeshGrpcConfiguration eventMeshGrpcConfiguration; @@ -69,8 +70,6 @@ public class EventMeshGrpcServer { private Server server; - private ProducerManager producerManager; - private ConsumerManager consumerManager; private GrpcRetryer grpcRetryer; @@ -87,7 +86,7 @@ public class EventMeshGrpcServer { private RateLimiter msgRateLimiter; - private final Registry registry; + private final MetaStorage metaStorage; private final Acl acl; @@ -98,7 +97,7 @@ public class EventMeshGrpcServer { public EventMeshGrpcServer(final EventMeshServer eventMeshServer, final EventMeshGrpcConfiguration eventMeshGrpcConfiguration) { this.eventMeshServer = eventMeshServer; this.eventMeshGrpcConfiguration = eventMeshGrpcConfiguration; - this.registry = eventMeshServer.getRegistry(); + this.metaStorage = eventMeshServer.getMetaStorage(); this.acl = eventMeshServer.getAcl(); } @@ -111,21 +110,18 @@ public void init() throws Exception { msgRateLimiter = RateLimiter.create(eventMeshGrpcConfiguration.getEventMeshMsgReqNumPerSecond()); - producerManager = new ProducerManager(this); - producerManager.init(); - + initProducerManager(); consumerManager = new ConsumerManager(this); consumerManager.init(); grpcRetryer = new GrpcRetryer(this); - grpcRetryer.init(); int serverPort = eventMeshGrpcConfiguration.getGrpcServerPort(); server = ServerBuilder.forPort(serverPort) - .addService(new ProducerService(this, sendMsgExecutor)) - .addService(new ConsumerService(this, clientMgmtExecutor, replyMsgExecutor)) - .addService(new HeartbeatService(this, clientMgmtExecutor)) + .addService(new ConsumerService(this, sendMsgExecutor, replyMsgExecutor)) + .addService(new HeartbeatService(this, sendMsgExecutor)) + .addService(new PublisherService(this, sendMsgExecutor)) .build(); initMetricsMonitor(); @@ -134,6 +130,11 @@ public void init() throws Exception { log.info("-----------------EventMeshGRPCServer initialized"); } + @Override + public CommonConfiguration getConfiguration() { + return eventMeshGrpcConfiguration; + } + public void start() throws Exception { log.info("---------------EventMeshGRPCServer starting-------------------"); @@ -142,7 +143,7 @@ public void start() throws Exception { grpcRetryer.start(); server.start(); - if (eventMeshGrpcConfiguration.isEventMeshServerRegistryEnable()) { + if (eventMeshGrpcConfiguration.isEventMeshServerMetaStorageEnable()) { this.register(); } @@ -162,7 +163,7 @@ public void shutdown() throws Exception { server.shutdown(); - if (eventMeshGrpcConfiguration.isEventMeshServerRegistryEnable()) { + if (eventMeshGrpcConfiguration.isEventMeshServerMetaStorageEnable()) { this.unRegister(); } @@ -178,10 +179,10 @@ public boolean register() { EventMeshRegisterInfo eventMeshRegisterInfo = new EventMeshRegisterInfo(); eventMeshRegisterInfo.setEventMeshClusterName(eventMeshGrpcConfiguration.getEventMeshCluster()); eventMeshRegisterInfo.setEventMeshName(eventMeshGrpcConfiguration.getEventMeshName() + "-" - + ConfigurationContextUtil.GRPC); + + GRPC); eventMeshRegisterInfo.setEndPoint(endPoints); - eventMeshRegisterInfo.setProtocolType(ConfigurationContextUtil.GRPC); - registerResult = registry.register(eventMeshRegisterInfo); + eventMeshRegisterInfo.setProtocolType(GRPC); + registerResult = metaStorage.register(eventMeshRegisterInfo); } catch (Exception e) { log.warn("eventMesh register to registry failed", e); } @@ -196,8 +197,8 @@ private void unRegister() throws Exception { eventMeshUnRegisterInfo.setEventMeshClusterName(eventMeshGrpcConfiguration.getEventMeshCluster()); eventMeshUnRegisterInfo.setEventMeshName(eventMeshGrpcConfiguration.getEventMeshName()); eventMeshUnRegisterInfo.setEndPoint(endPoints); - eventMeshUnRegisterInfo.setProtocolType(ConfigurationContextUtil.GRPC); - boolean registerResult = registry.unRegister(eventMeshUnRegisterInfo); + eventMeshUnRegisterInfo.setProtocolType(GRPC); + boolean registerResult = metaStorage.unRegister(eventMeshUnRegisterInfo); if (!registerResult) { throw new EventMeshException("eventMesh fail to unRegister"); } @@ -207,10 +208,6 @@ public EventMeshGrpcConfiguration getEventMeshGrpcConfiguration() { return this.eventMeshGrpcConfiguration; } - public ProducerManager getProducerManager() { - return producerManager; - } - public ConsumerManager getConsumerManager() { return consumerManager; } @@ -276,7 +273,7 @@ private void initThreadPool() { } private void initHttpClientPool() { - httpClientPool = new LinkedList<>(); + httpClientPool = new ArrayList<>(); int clientPool = RandomUtils.nextInt(MIN_LIMIT, MAX_LIMIT); for (int i = 0; i < clientPool; i++) { CloseableHttpClient client = HttpClients.createDefault(); @@ -314,8 +311,8 @@ private void shutdownHttpClientPool() { } } - public Registry getRegistry() { - return registry; + public MetaStorage getMetaStorage() { + return metaStorage; } public Acl getAcl() { 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 index 5036f6660d..05e90d482f 100644 --- 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 @@ -17,12 +17,12 @@ 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 static org.apache.eventmesh.common.Constants.HTTP; + +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; 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; @@ -34,10 +34,13 @@ 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.CreateTopicProcessor; +import org.apache.eventmesh.runtime.core.protocol.http.processor.DeleteTopicProcessor; 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.QuerySubscriptionProcessor; 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; @@ -48,174 +51,84 @@ 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.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.core.protocol.producer.ProducerManager; +import org.apache.eventmesh.runtime.meta.MetaStorage; 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.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; import lombok.extern.slf4j.Slf4j; +/** + * Add multiple managers to the underlying server + */ @Slf4j public class EventMeshHTTPServer extends AbstractHTTPServer { private final EventMeshServer eventMeshServer; - private final EventMeshHTTPConfiguration eventMeshHttpConfiguration; - private final Registry registry; + private final MetaStorage metaStorage; private final Acl acl; - - public final EventBus eventBus = new EventBus(); + private final EventBus eventBus = new EventBus(); private ConsumerManager consumerManager; - - private SubscriptionManager subscriptionManager; - private ProducerManager producerManager; + private SubscriptionManager subscriptionManager; - private HttpRetryer httpRetryer; - - private ThreadPoolExecutor batchMsgExecutor; - - private ThreadPoolExecutor sendMsgExecutor; - - private ThreadPoolExecutor remoteMsgExecutor; - - private ThreadPoolExecutor replyMsgExecutor; - - private ThreadPoolExecutor pushMsgExecutor; - - private ThreadPoolExecutor clientManageExecutor; + private FilterEngine filterEngine; - private ThreadPoolExecutor adminExecutor; + private TransformerEngine transformerEngine; - private ThreadPoolExecutor webhookExecutor; + private HttpRetryer httpRetryer; private transient RateLimiter msgRateLimiter; - private transient RateLimiter batchRateLimiter; private final transient HTTPClientPool httpClientPool = new HTTPClientPool(10); public EventMeshHTTPServer(final EventMeshServer eventMeshServer, final EventMeshHTTPConfiguration eventMeshHttpConfiguration) { - super(eventMeshHttpConfiguration.getHttpServerPort(), eventMeshHttpConfiguration.isEventMeshServerUseTls(), eventMeshHttpConfiguration); + super(eventMeshHttpConfiguration.getHttpServerPort(), + eventMeshHttpConfiguration.isEventMeshServerUseTls(), + eventMeshHttpConfiguration); this.eventMeshServer = eventMeshServer; this.eventMeshHttpConfiguration = eventMeshHttpConfiguration; - this.registry = eventMeshServer.getRegistry(); + this.metaStorage = eventMeshServer.getMetaStorage(); this.acl = eventMeshServer.getAcl(); } - private void initThreadPool() { - - batchMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshHttpConfiguration.getEventMeshServerBatchMsgThreadNum(), - eventMeshHttpConfiguration.getEventMeshServerBatchMsgThreadNum(), - new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerBatchBlockQSize()), - "eventMesh-batchMsg", true); - - sendMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshHttpConfiguration.getEventMeshServerSendMsgThreadNum(), - eventMeshHttpConfiguration.getEventMeshServerSendMsgThreadNum(), - new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerSendMsgBlockQSize()), - "eventMesh-sendMsg", true); - - remoteMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshHttpConfiguration.getEventMeshServerRemoteMsgThreadNum(), - eventMeshHttpConfiguration.getEventMeshServerRemoteMsgThreadNum(), - new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerRemoteMsgBlockQSize()), - "eventMesh-remoteMsg", true); - - pushMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshHttpConfiguration.getEventMeshServerPushMsgThreadNum(), - eventMeshHttpConfiguration.getEventMeshServerPushMsgThreadNum(), - new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerPushMsgBlockQSize()), - "eventMesh-pushMsg", true); - - clientManageExecutor = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshHttpConfiguration.getEventMeshServerClientManageThreadNum(), - eventMeshHttpConfiguration.getEventMeshServerClientManageThreadNum(), - new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerClientManageBlockQSize()), - "eventMesh-clientManage", true); - - adminExecutor = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshHttpConfiguration.getEventMeshServerAdminThreadNum(), - eventMeshHttpConfiguration.getEventMeshServerAdminThreadNum(), - new LinkedBlockingQueue<>(50), "eventMesh-admin", - true); - - replyMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshHttpConfiguration.getEventMeshServerReplyMsgThreadNum(), - eventMeshHttpConfiguration.getEventMeshServerReplyMsgThreadNum(), - new LinkedBlockingQueue<>(100), - "eventMesh-replyMsg", true); - } - - public void shutdownThreadPool() { - if (batchMsgExecutor != null) { - batchMsgExecutor.shutdown(); - } - if (adminExecutor != null) { - adminExecutor.shutdown(); - } - if (clientManageExecutor != null) { - clientManageExecutor.shutdown(); - } - if (sendMsgExecutor != null) { - sendMsgExecutor.shutdown(); - } - if (remoteMsgExecutor != null) { - remoteMsgExecutor.shutdown(); - } - if (pushMsgExecutor != null) { - pushMsgExecutor.shutdown(); - } - if (replyMsgExecutor != null) { - replyMsgExecutor.shutdown(); - } - } - - private void init() throws Exception { - if (log.isInfoEnabled()) { - log.info("==================EventMeshHTTPServer Initialing=================="); - } - super.init("eventMesh-http"); - - initThreadPool(); + public void init() throws Exception { + log.info("==================EventMeshHTTPServer Initialing=================="); + super.init(); msgRateLimiter = RateLimiter.create(eventMeshHttpConfiguration.getEventMeshHttpMsgReqNumPerSecond()); batchRateLimiter = RateLimiter.create(eventMeshHttpConfiguration.getEventMeshBatchMsgRequestNumPerSecond()); // The MetricsRegistry is singleton, so we can use factory method to get. final List metricsRegistries = Lists.newArrayList(); - Optional.ofNullable(eventMeshHttpConfiguration.getEventMeshMetricsPluginType()) - .ifPresent( - metricsPlugins -> metricsPlugins.forEach( - pluginType -> metricsRegistries.add(MetricsPluginFactory.getMetricsRegistry(pluginType)))); + Optional.ofNullable(eventMeshHttpConfiguration.getEventMeshMetricsPluginType()).ifPresent( + metricsPlugins -> metricsPlugins.forEach( + pluginType -> metricsRegistries.add(MetricsPluginFactory.getMetricsRegistry(pluginType)))); httpRetryer = new HttpRetryer(this); - httpRetryer.init(); - this.setMetrics(new HTTPMetricsServer(this, metricsRegistries)); - - subscriptionManager = new SubscriptionManager(); + super.setMetrics(new HTTPMetricsServer(this, metricsRegistries)); + subscriptionManager = new SubscriptionManager(eventMeshHttpConfiguration.isEventMeshServerMetaStorageEnable(), metaStorage); consumerManager = new ConsumerManager(this); consumerManager.init(); @@ -223,39 +136,42 @@ private void init() throws Exception { producerManager = new ProducerManager(this); producerManager.init(); - this.setHandlerService(new HandlerService()); - this.getHandlerService().setMetrics(this.getMetrics()); + filterEngine = new FilterEngine(metaStorage, producerManager, consumerManager); + + transformerEngine = new TransformerEngine(metaStorage, producerManager, consumerManager); - //get the trace-plugin + super.setHandlerService(new HandlerService()); + super.getHandlerService().setMetrics(this.getMetrics()); + + // get the trace-plugin if (StringUtils.isNotEmpty(eventMeshHttpConfiguration.getEventMeshTracePluginType()) && eventMeshHttpConfiguration.isEventMeshServerTraceEnable()) { - - this.setUseTrace(eventMeshHttpConfiguration.isEventMeshServerTraceEnable()); + super.setUseTrace(eventMeshHttpConfiguration.isEventMeshServerTraceEnable()); } - - this.getHandlerService().setHttpTrace(new HTTPTrace(eventMeshHttpConfiguration.isEventMeshServerTraceEnable())); + super.getHandlerService().setHttpTrace(new HTTPTrace(eventMeshHttpConfiguration.isEventMeshServerTraceEnable())); registerHTTPRequestProcessor(); - this.initWebhook(); - if (log.isInfoEnabled()) { - log.info("==================EventMeshHTTPServer initialized=================="); - } + + log.info("==================EventMeshHTTPServer initialized=================="); } @Override public void start() throws Exception { - init(); super.start(); this.getMetrics().start(); + consumerManager.start(); producerManager.start(); httpRetryer.start(); - if (eventMeshHttpConfiguration.isEventMeshServerRegistryEnable()) { - this.register(); + // filterEngine depend on metaStorage + if (metaStorage.getStarted().get()) { + filterEngine.start(); } - if (log.isInfoEnabled()) { - log.info("==================EventMeshHTTPServer started=================="); + + if (eventMeshHttpConfiguration.isEventMeshServerMetaStorageEnable()) { + this.register(); } + log.info("==================EventMeshHTTPServer started=================="); } @Override @@ -265,9 +181,11 @@ public void shutdown() throws Exception { this.getMetrics().shutdown(); - consumerManager.shutdown(); + filterEngine.shutdown(); + + transformerEngine.shutdown(); - shutdownThreadPool(); + consumerManager.shutdown(); httpClientPool.shutdown(); @@ -275,14 +193,15 @@ public void shutdown() throws Exception { httpRetryer.shutdown(); - if (eventMeshHttpConfiguration.isEventMeshServerRegistryEnable()) { + if (eventMeshHttpConfiguration.isEventMeshServerMetaStorageEnable()) { this.unRegister(); } - if (log.isInfoEnabled()) { - log.info("==================EventMeshHTTPServer shutdown=================="); - } + log.info("==================EventMeshHTTPServer shutdown=================="); } + /** + * Related to the registry module + */ public boolean register() { boolean registerResult = false; try { @@ -291,10 +210,10 @@ public boolean register() { final EventMeshRegisterInfo eventMeshRegisterInfo = new EventMeshRegisterInfo(); eventMeshRegisterInfo.setEventMeshClusterName(eventMeshHttpConfiguration.getEventMeshCluster()); eventMeshRegisterInfo.setEventMeshName(eventMeshHttpConfiguration.getEventMeshName() - + "-" + ConfigurationContextUtil.HTTP); + + "-" + HTTP); eventMeshRegisterInfo.setEndPoint(endPoints); - eventMeshRegisterInfo.setProtocolType(ConfigurationContextUtil.HTTP); - registerResult = registry.register(eventMeshRegisterInfo); + eventMeshRegisterInfo.setProtocolType(HTTP); + registerResult = metaStorage.register(eventMeshRegisterInfo); } catch (Exception e) { log.error("eventMesh register to registry failed", e); } @@ -302,21 +221,27 @@ public boolean register() { return registerResult; } - private void unRegister() throws Exception { + /** + * Related to the registry module + */ + private void unRegister() { final String endPoints = IPUtils.getLocalAddress() + EventMeshConstants.IP_PORT_SEPARATOR + eventMeshHttpConfiguration.getHttpServerPort(); final EventMeshUnRegisterInfo eventMeshUnRegisterInfo = new EventMeshUnRegisterInfo(); eventMeshUnRegisterInfo.setEventMeshClusterName(eventMeshHttpConfiguration.getEventMeshCluster()); eventMeshUnRegisterInfo.setEventMeshName(eventMeshHttpConfiguration.getEventMeshName()); eventMeshUnRegisterInfo.setEndPoint(endPoints); - eventMeshUnRegisterInfo.setProtocolType(ConfigurationContextUtil.HTTP); - final boolean registerResult = registry.unRegister(eventMeshUnRegisterInfo); + eventMeshUnRegisterInfo.setProtocolType(HTTP); + final boolean registerResult = metaStorage.unRegister(eventMeshUnRegisterInfo); if (!registerResult) { throw new EventMeshException("eventMesh fail to unRegister"); } } - public void registerHTTPRequestProcessor() { + private void registerHTTPRequestProcessor() throws Exception { + HTTPThreadPoolGroup httpThreadPoolGroup = super.getHttpThreadPoolGroup(); + + ThreadPoolExecutor batchMsgExecutor = httpThreadPoolGroup.getBatchMsgExecutor(); final BatchSendMessageProcessor batchSendMessageProcessor = new BatchSendMessageProcessor(this); registerProcessor(RequestCode.MSG_BATCH_SEND.getRequestCode(), batchSendMessageProcessor, batchMsgExecutor); @@ -324,6 +249,7 @@ public void registerHTTPRequestProcessor() { registerProcessor(RequestCode.MSG_BATCH_SEND_V2.getRequestCode(), batchSendMessageV2Processor, batchMsgExecutor); + ThreadPoolExecutor sendMsgExecutor = httpThreadPoolGroup.getSendMsgExecutor(); final SendSyncMessageProcessor sendSyncMessageProcessor = new SendSyncMessageProcessor(this); registerProcessor(RequestCode.MSG_SEND_SYNC.getRequestCode(), sendSyncMessageProcessor, sendMsgExecutor); @@ -333,12 +259,15 @@ public void registerHTTPRequestProcessor() { final SendAsyncEventProcessor sendAsyncEventProcessor = new SendAsyncEventProcessor(this); this.getHandlerService().register(sendAsyncEventProcessor, sendMsgExecutor); + ThreadPoolExecutor remoteMsgExecutor = httpThreadPoolGroup.getRemoteMsgExecutor(); final SendAsyncRemoteEventProcessor sendAsyncRemoteEventProcessor = new SendAsyncRemoteEventProcessor(this); this.getHandlerService().register(sendAsyncRemoteEventProcessor, remoteMsgExecutor); + ThreadPoolExecutor runtimeAdminExecutor = httpThreadPoolGroup.getRuntimeAdminExecutor(); final AdminMetricsProcessor adminMetricsProcessor = new AdminMetricsProcessor(this); - registerProcessor(RequestCode.ADMIN_METRICS.getRequestCode(), adminMetricsProcessor, adminExecutor); + registerProcessor(RequestCode.ADMIN_METRICS.getRequestCode(), adminMetricsProcessor, runtimeAdminExecutor); + ThreadPoolExecutor clientManageExecutor = httpThreadPoolGroup.getClientManageExecutor(); final HeartBeatProcessor heartProcessor = new HeartBeatProcessor(this); registerProcessor(RequestCode.HEARTBEAT.getRequestCode(), heartProcessor, clientManageExecutor); @@ -360,23 +289,30 @@ public void registerHTTPRequestProcessor() { final RemoteUnSubscribeEventProcessor remoteUnSubscribeEventProcessor = new RemoteUnSubscribeEventProcessor(this); this.getHandlerService().register(remoteUnSubscribeEventProcessor, clientManageExecutor); + ThreadPoolExecutor replyMsgExecutor = httpThreadPoolGroup.getReplyMsgExecutor(); final ReplyMessageProcessor replyMessageProcessor = new ReplyMessageProcessor(this); registerProcessor(RequestCode.REPLY_MESSAGE.getRequestCode(), replyMessageProcessor, replyMsgExecutor); - } + final CreateTopicProcessor createTopicProcessor = new CreateTopicProcessor(this); + this.getHandlerService().register(createTopicProcessor, clientManageExecutor); - private void initWebhook() throws Exception { + final DeleteTopicProcessor deleteTopicProcessor = new DeleteTopicProcessor(this); + this.getHandlerService().register(deleteTopicProcessor, clientManageExecutor); - webhookExecutor = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshHttpConfiguration.getEventMeshServerWebhookThreadNum(), - eventMeshHttpConfiguration.getEventMeshServerWebhookThreadNum(), - new LinkedBlockingQueue<>(100), "eventMesh-webhook", true); - final WebHookProcessor webHookProcessor = new WebHookProcessor(); + final QuerySubscriptionProcessor querySubscriptionProcessor = new QuerySubscriptionProcessor(this); + this.getHandlerService().register(querySubscriptionProcessor, clientManageExecutor); + registerWebhook(); + } + + private void registerWebhook() throws Exception { + final WebHookProcessor webHookProcessor = new WebHookProcessor(); final WebHookController webHookController = new WebHookController(); + webHookController.init(); webHookProcessor.setWebHookController(webHookController); - this.getHandlerService().register(webHookProcessor, webhookExecutor); + + this.getHandlerService().register(webHookProcessor, super.getHttpThreadPoolGroup().getWebhookExecutor()); } public SubscriptionManager getSubscriptionManager() { @@ -411,30 +347,6 @@ public EventMeshServer getEventMeshServer() { return eventMeshServer; } - 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; } @@ -443,8 +355,16 @@ public RateLimiter getBatchRateLimiter() { return batchRateLimiter; } - public Registry getRegistry() { - return registry; + public FilterEngine getFilterEngine() { + return filterEngine; + } + + public TransformerEngine getTransformerEngine() { + return transformerEngine; + } + + public MetaStorage getMetaStorage() { + return metaStorage; } public HTTPClientPool getHttpClientPool() { diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshHttpBootstrap.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshHttpBootstrap.java index 95512b7e5c..87ce3c23a4 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshHttpBootstrap.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshHttpBootstrap.java @@ -17,6 +17,8 @@ package org.apache.eventmesh.runtime.boot; +import static org.apache.eventmesh.common.Constants.HTTP; + import org.apache.eventmesh.common.config.ConfigService; import org.apache.eventmesh.common.utils.ConfigurationContextUtil; import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration; @@ -35,7 +37,7 @@ public EventMeshHttpBootstrap(final EventMeshServer eventMeshServer) { ConfigService configService = ConfigService.getInstance(); this.eventMeshHttpConfiguration = configService.buildConfigInstance(EventMeshHTTPConfiguration.class); - ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.HTTP, eventMeshHttpConfiguration); + ConfigurationContextUtil.putIfAbsent(HTTP, eventMeshHttpConfiguration); } @Override @@ -43,6 +45,7 @@ public void init() throws Exception { // server init if (eventMeshHttpConfiguration != null) { eventMeshHttpServer = new EventMeshHTTPServer(eventMeshServer, eventMeshHttpConfiguration); + eventMeshHttpServer.init(); } } @@ -56,7 +59,7 @@ public void start() throws Exception { @Override public void shutdown() throws Exception { - //server shutdown + // server shutdown if (eventMeshHttpServer != null) { eventMeshHttpServer.shutdown(); } 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 index b08f4e89e4..11e16cab8c 100644 --- 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 @@ -17,6 +17,10 @@ package org.apache.eventmesh.runtime.boot; +import static org.apache.eventmesh.common.Constants.GRPC; +import static org.apache.eventmesh.common.Constants.HTTP; +import static org.apache.eventmesh.common.Constants.TCP; + import org.apache.eventmesh.common.config.CommonConfiguration; import org.apache.eventmesh.common.config.ConfigService; import org.apache.eventmesh.common.utils.AssertUtils; @@ -26,7 +30,7 @@ import org.apache.eventmesh.runtime.common.ServiceState; import org.apache.eventmesh.runtime.constants.EventMeshConstants; import org.apache.eventmesh.runtime.core.protocol.http.producer.ProducerTopicManager; -import org.apache.eventmesh.runtime.registry.Registry; +import org.apache.eventmesh.runtime.meta.MetaStorage; import org.apache.eventmesh.runtime.storage.StorageResource; import org.apache.eventmesh.runtime.trace.Trace; @@ -34,7 +38,6 @@ import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -42,7 +45,7 @@ public class EventMeshServer { private final Acl acl; - private Registry registry; + private MetaStorage metaStorage; private static Trace trace; @@ -64,35 +67,35 @@ public class EventMeshServer { public EventMeshServer() { - //Initialize configuration + // Initialize configuration this.configuration = configService.buildConfigInstance(CommonConfiguration.class); AssertUtils.notNull(this.configuration, "configuration is null"); - //Initialize acl, registry, trace and storageResource + // Initialize acl, registry, trace and storageResource this.acl = Acl.getInstance(this.configuration.getEventMeshSecurityPluginType()); - this.registry = Registry.getInstance(this.configuration.getEventMeshRegistryPluginType()); + this.metaStorage = MetaStorage.getInstance(this.configuration.getEventMeshMetaStoragePluginType()); trace = Trace.getInstance(this.configuration.getEventMeshTracePluginType(), this.configuration.isEventMeshServerTraceEnable()); this.storageResource = StorageResource.getInstance(this.configuration.getEventMeshStoragePluginType()); - //Initialize BOOTSTRAP_LIST based on protocols provided in configuration + // Initialize BOOTSTRAP_LIST based on protocols provided in configuration final List provideServerProtocols = configuration.getEventMeshProvideServerProtocols(); - for (final String provideServerProtocol : provideServerProtocols) { - switch (provideServerProtocol) { - case ConfigurationContextUtil.HTTP: + for (String provideServerProtocol : provideServerProtocols) { + switch (provideServerProtocol.toUpperCase()) { + case HTTP: BOOTSTRAP_LIST.add(new EventMeshHttpBootstrap(this)); break; - case ConfigurationContextUtil.TCP: + case TCP: BOOTSTRAP_LIST.add(new EventMeshTcpBootstrap(this)); break; - case ConfigurationContextUtil.GRPC: + case GRPC: BOOTSTRAP_LIST.add(new EventMeshGrpcBootstrap(this)); break; default: - //nothing to do + // nothing to do } } - //If no protocols are provided, initialize BOOTSTRAP_LIST with default protocols + // If no protocols are provided, initialize BOOTSTRAP_LIST with default protocols if (BOOTSTRAP_LIST.isEmpty()) { BOOTSTRAP_LIST.add(new EventMeshTcpBootstrap(this)); } @@ -103,8 +106,8 @@ public void init() throws Exception { if (configuration.isEventMeshServerSecurityEnable()) { acl.init(); } - if (configuration.isEventMeshServerRegistryEnable()) { - registry.init(); + if (configuration.isEventMeshServerMetaStorageEnable()) { + metaStorage.init(); } if (configuration.isEventMeshServerTraceEnable()) { trace.init(); @@ -132,22 +135,18 @@ public void init() throws Exception { if (Objects.nonNull(eventMeshTCPServer) && Objects.nonNull(eventMeshHTTPServer) && Objects.nonNull(eventMeshGrpcServer)) { - clientManageController = new ClientManageController(eventMeshTCPServer, eventMeshHTTPServer, eventMeshGrpcServer, registry); + clientManageController = new ClientManageController(eventMeshTCPServer, eventMeshHTTPServer, eventMeshGrpcServer, metaStorage); clientManageController.setAdminWebHookConfigOperationManage(eventMeshTCPServer.getAdminWebHookConfigOperationManage()); } final String eventStore = System.getProperty(EventMeshConstants.EVENT_STORE_PROPERTIES, System.getenv(EventMeshConstants.EVENT_STORE_ENV)); - if (log.isInfoEnabled()) { - log.info("eventStore : {}", eventStore); - } + log.info("eventStore : {}", eventStore); producerTopicManager = new ProducerTopicManager(this); producerTopicManager.init(); serviceState = ServiceState.INITED; - if (log.isInfoEnabled()) { - log.info(SERVER_STATE_MSG, serviceState); - } + log.info(SERVER_STATE_MSG, serviceState); } public void start() throws Exception { @@ -156,8 +155,8 @@ public void start() throws Exception { acl.start(); } // registry start - if (configuration.isEventMeshServerRegistryEnable()) { - registry.start(); + if (configuration.isEventMeshServerMetaStorageEnable()) { + metaStorage.start(); } } // server start @@ -170,24 +169,20 @@ public void start() throws Exception { } producerTopicManager.start(); serviceState = ServiceState.RUNNING; - if (log.isInfoEnabled()) { - log.info(SERVER_STATE_MSG, serviceState); - } + log.info(SERVER_STATE_MSG, serviceState); } public void shutdown() throws Exception { serviceState = ServiceState.STOPPING; - if (log.isInfoEnabled()) { - log.info(SERVER_STATE_MSG, serviceState); - } + log.info(SERVER_STATE_MSG, serviceState); for (final EventMeshBootstrap eventMeshBootstrap : BOOTSTRAP_LIST) { eventMeshBootstrap.shutdown(); } - if (configuration != null && configuration.isEventMeshServerRegistryEnable()) { - registry.shutdown(); + if (configuration != null && configuration.isEventMeshServerMetaStorageEnable()) { + metaStorage.shutdown(); } storageResource.release(); @@ -203,9 +198,7 @@ public void shutdown() throws Exception { ConfigurationContextUtil.clear(); serviceState = ServiceState.STOPPED; - if (log.isInfoEnabled()) { - log.info(SERVER_STATE_MSG, serviceState); - } + log.info(SERVER_STATE_MSG, serviceState); } public static Trace getTrace() { @@ -216,12 +209,12 @@ public ServiceState getServiceState() { return serviceState; } - public Registry getRegistry() { - return registry; + public MetaStorage getMetaStorage() { + return metaStorage; } - public void setRegistry(final Registry registry) { - this.registry = registry; + public void setMetaStorage(final MetaStorage metaStorage) { + this.metaStorage = metaStorage; } public Acl getAcl() { 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 index 21b97c69f0..5c6ae90aae 100644 --- 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 @@ -40,15 +40,12 @@ public static void main(String[] args) throws Exception { server.start(); Runtime.getRuntime().addShutdownHook(new Thread(() -> { try { - if (log.isInfoEnabled()) { - log.info("eventMesh shutting down hook begin."); - } + log.info("eventMesh shutting down hook begin."); long start = System.currentTimeMillis(); server.shutdown(); long end = System.currentTimeMillis(); - if (log.isInfoEnabled()) { - log.info("eventMesh shutdown cost {}ms", end - start); - } + + log.info("eventMesh shutdown cost {}ms", end - start); } catch (Exception e) { log.error("exception when shutdown.", e); } @@ -60,4 +57,3 @@ public static void main(String[] args) throws Exception { } } - 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 index 67b56ed6df..7c81501d98 100644 --- 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 @@ -17,13 +17,12 @@ 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.EventMeshThreadFactory; -import org.apache.eventmesh.common.ThreadPoolFactory; +import static org.apache.eventmesh.common.Constants.TCP; + +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; 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.protocol.tcp.Command; import org.apache.eventmesh.common.utils.IPUtils; import org.apache.eventmesh.common.utils.ThreadUtils; import org.apache.eventmesh.metrics.api.MetricsPluginFactory; @@ -31,274 +30,137 @@ import org.apache.eventmesh.runtime.acl.Acl; 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.processor.GoodbyeProcessor; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.processor.HeartBeatProcessor; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.processor.HelloProcessor; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.processor.ListenProcessor; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.processor.MessageAckProcessor; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.processor.MessageTransferProcessor; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.processor.RecommendProcessor; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.processor.SubscribeProcessor; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.processor.UnSubscribeProcessor; import org.apache.eventmesh.runtime.core.protocol.tcp.client.rebalance.EventMeshRebalanceImpl; import org.apache.eventmesh.runtime.core.protocol.tcp.client.rebalance.EventMeshRebalanceService; -import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.retry.EventMeshTcpRetryer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.retry.TcpRetryer; +import org.apache.eventmesh.runtime.meta.MetaStorage; import org.apache.eventmesh.runtime.metrics.tcp.EventMeshTcpMonitor; -import org.apache.eventmesh.runtime.registry.Registry; import org.apache.eventmesh.webhook.admin.AdminWebHookConfigOperationManager; 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.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; 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.epoll.EpollServerSocketChannel; -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; import lombok.extern.slf4j.Slf4j; +/** + * Add multiple managers to the underlying server + */ @Slf4j -public class EventMeshTCPServer extends AbstractRemotingServer { - - private ClientSessionGroupMapping clientSessionGroupMapping; - - private transient EventMeshTcpRetryer eventMeshTcpRetryer; - - private transient EventMeshTcpMonitor eventMeshTcpMonitor; - - private final transient EventMeshServer eventMeshServer; - - private final transient EventMeshTCPConfiguration eventMeshTCPConfiguration; - - private transient GlobalTrafficShapingHandler globalTrafficShapingHandler; - - private EventMeshTcpConnectionHandler eventMeshTcpConnectionHandler; +public class EventMeshTCPServer extends AbstractTCPServer { - private transient ScheduledExecutorService scheduler; - - private transient ExecutorService taskHandleExecutorService; - - private transient ExecutorService broadcastMsgDownstreamExecutorService; - - private final transient Registry registry; + private final EventMeshServer eventMeshServer; + private final EventMeshTCPConfiguration eventMeshTCPConfiguration; + private final MetaStorage metaStorage; private final Acl acl; - private transient EventMeshRebalanceService eventMeshRebalanceService; - - private transient AdminWebHookConfigOperationManager adminWebHookConfigOperationManage; - - private transient RateLimiter rateLimiter; - - - public void setClientSessionGroupMapping(final ClientSessionGroupMapping clientSessionGroupMapping) { - this.clientSessionGroupMapping = clientSessionGroupMapping; - } - - public ScheduledExecutorService getScheduler() { - return scheduler; - } - - public void setScheduler(final ScheduledExecutorService scheduler) { - this.scheduler = scheduler; - } - - public ExecutorService getTaskHandleExecutorService() { - return taskHandleExecutorService; - } - - public ExecutorService getBroadcastMsgDownstreamExecutorService() { - return broadcastMsgDownstreamExecutorService; - } - - public void setTaskHandleExecutorService(final ExecutorService taskHandleExecutorService) { - this.taskHandleExecutorService = taskHandleExecutorService; - } + private ClientSessionGroupMapping clientSessionGroupMapping; - public RateLimiter getRateLimiter() { - return rateLimiter; - } + private TcpRetryer tcpRetryer; - public void setRateLimiter(final RateLimiter rateLimiter) { - this.rateLimiter = rateLimiter; - } + private AdminWebHookConfigOperationManager adminWebHookConfigOperationManage; + private RateLimiter rateLimiter; + private EventMeshRebalanceService eventMeshRebalanceService; public EventMeshTCPServer(final EventMeshServer eventMeshServer, final EventMeshTCPConfiguration eventMeshTCPConfiguration) { - super(); + super(eventMeshTCPConfiguration); this.eventMeshServer = eventMeshServer; this.eventMeshTCPConfiguration = eventMeshTCPConfiguration; - this.registry = eventMeshServer.getRegistry(); + this.metaStorage = eventMeshServer.getMetaStorage(); this.acl = eventMeshServer.getAcl(); } - private void startServer() { - Runnable runnable = () -> { - ServerBootstrap bootstrap = new ServerBootstrap(); - ChannelInitializer channelInitializer = new ChannelInitializer() { - @Override - public void initChannel(final Channel ch) throws Exception { - ch.pipeline() - .addLast(getWorkerGroup(), new Codec.Encoder()) - .addLast(getWorkerGroup(), new Codec.Decoder()) - .addLast(getWorkerGroup(), "global-traffic-shaping", globalTrafficShapingHandler) - .addLast(getWorkerGroup(), "channel-traffic-shaping", newCTSHandler(eventMeshTCPConfiguration.getCtc().getReadLimit())) - .addLast(getWorkerGroup(), eventMeshTcpConnectionHandler) - .addLast(getWorkerGroup(), - new IdleStateHandler( - eventMeshTCPConfiguration.getEventMeshTcpIdleReadSeconds(), - eventMeshTCPConfiguration.getEventMeshTcpIdleWriteSeconds(), - eventMeshTCPConfiguration.getEventMeshTcpIdleAllSeconds()), - new EventMeshTcpMessageDispatcher(EventMeshTCPServer.this), - new EventMeshTcpExceptionHandler(EventMeshTCPServer.this) - ); - } - }; - - bootstrap.group(this.getBossGroup(), this.getIoGroup()) - .channel(useEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class) - .option(ChannelOption.SO_BACKLOG, 128) - .option(ChannelOption.SO_REUSEADDR, true) - .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) - .childOption(ChannelOption.SO_KEEPALIVE, false) - .childOption(ChannelOption.SO_LINGER, 0) - .childOption(ChannelOption.SO_TIMEOUT, 600_000) - .childOption(ChannelOption.TCP_NODELAY, true) - .childOption(ChannelOption.SO_SNDBUF, 65_535 * 4) - .childOption(ChannelOption.SO_RCVBUF, 65_535 * 4) - .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(2_048, 4_096, 65_536)) - .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) - .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) - .childHandler(channelInitializer); - - try { - int port = eventMeshTCPConfiguration.getEventMeshTcpServerPort(); - ChannelFuture f = bootstrap.bind(port).sync(); - log.info("EventMeshTCPServer[port={}] started.....", port); - f.channel().closeFuture().sync(); - } catch (Exception e) { - log.error("EventMeshTCPServer RemotingServer Start Err!", e); - try { - shutdown(); - } catch (Exception ex) { - log.error("EventMeshTCPServer RemotingServer shutdown Err!", ex); - } - } - }; - - Thread thread = new Thread(runnable, "eventMesh-tcp-server"); - thread.start(); - } - public void init() throws Exception { - if (log.isInfoEnabled()) { - log.info("==================EventMeshTCPServer Initialing=================="); - } - initThreadPool(); + log.info("==================EventMeshTCPServer Initialing=================="); + super.init(); rateLimiter = RateLimiter.create(eventMeshTCPConfiguration.getEventMeshTcpMsgReqnumPerSecond()); - globalTrafficShapingHandler = newGTSHandler(scheduler, eventMeshTCPConfiguration.getGtc().getReadLimit()); - - eventMeshTcpConnectionHandler = new EventMeshTcpConnectionHandler(this); + // The MetricsRegistry is singleton, so we can use factory method to get. + final List metricsRegistries = Lists.newArrayList(); + Optional.ofNullable(eventMeshTCPConfiguration.getEventMeshMetricsPluginType()).ifPresent( + metricsPlugins -> metricsPlugins.forEach( + pluginType -> metricsRegistries.add(MetricsPluginFactory.getMetricsRegistry(pluginType)))); - adminWebHookConfigOperationManage = new AdminWebHookConfigOperationManager(); - adminWebHookConfigOperationManage.init(); + tcpRetryer = new TcpRetryer(this); clientSessionGroupMapping = new ClientSessionGroupMapping(this); clientSessionGroupMapping.init(); + super.setClientSessionGroupMapping(clientSessionGroupMapping); - eventMeshTcpRetryer = new EventMeshTcpRetryer(this); - eventMeshTcpRetryer.init(); + super.setEventMeshTcpMonitor(new EventMeshTcpMonitor(this, metricsRegistries)); + super.getEventMeshTcpMonitor().init(); - // The MetricsRegistry is singleton, so we can use factory method to get. - final List metricsRegistries = Lists.newArrayList(); - Optional.ofNullable(eventMeshTCPConfiguration.getEventMeshMetricsPluginType()) - .ifPresent( - metricsPlugins -> metricsPlugins.forEach( - pluginType -> metricsRegistries.add(MetricsPluginFactory.getMetricsRegistry(pluginType)))); - eventMeshTcpMonitor = new EventMeshTcpMonitor(this, metricsRegistries); - eventMeshTcpMonitor.init(); - - if (eventMeshTCPConfiguration.isEventMeshServerRegistryEnable()) { - eventMeshRebalanceService = new EventMeshRebalanceService(this, - new EventMeshRebalanceImpl(this)); + if (eventMeshTCPConfiguration.isEventMeshServerMetaStorageEnable()) { + eventMeshRebalanceService = new EventMeshRebalanceService(this, new EventMeshRebalanceImpl(this)); eventMeshRebalanceService.init(); } - if (log.isInfoEnabled()) { - log.info("--------------------------EventMeshTCPServer Inited"); - } + adminWebHookConfigOperationManage = new AdminWebHookConfigOperationManager(); + adminWebHookConfigOperationManage.init(); + + registerTCPRequestProcessor(); + + log.info("--------------------------EventMeshTCPServer Inited"); } @Override public void start() throws Exception { - startServer(); + super.start(); + super.getEventMeshTcpMonitor().start(); clientSessionGroupMapping.start(); + tcpRetryer.start(); - eventMeshTcpRetryer.start(); - - eventMeshTcpMonitor.start(); - - if (eventMeshTCPConfiguration.isEventMeshServerRegistryEnable()) { + if (eventMeshTCPConfiguration.isEventMeshServerMetaStorageEnable()) { this.register(); eventMeshRebalanceService.start(); } - if (log.isInfoEnabled()) { - log.info("--------------------------EventMeshTCPServer Started"); - } + log.info("--------------------------EventMeshTCPServer Started"); } @Override public void shutdown() throws Exception { - if (this.getBossGroup() != null) { - this.getBossGroup().shutdownGracefully(); - log.info("shutdown bossGroup, no client is allowed to connect access server"); - } + super.shutdown(); - if (eventMeshTCPConfiguration.isEventMeshServerRegistryEnable()) { - eventMeshRebalanceService.shutdown(); - - this.unRegister(); - } + super.getEventMeshTcpMonitor().shutdown(); clientSessionGroupMapping.shutdown(); ThreadUtils.sleep(40, TimeUnit.SECONDS); - globalTrafficShapingHandler.release(); - - if (this.getIoGroup() != null) { - this.getIoGroup().shutdownGracefully(); - log.info("shutdown ioGroup"); - } - if (this.getWorkerGroup() != null) { - this.getWorkerGroup().shutdownGracefully(); - log.info("shutdown workerGroup"); - } - eventMeshTcpRetryer.shutdown(); + tcpRetryer.shutdown(); - eventMeshTcpMonitor.shutdown(); - - shutdownThreadPool(); - if (log.isInfoEnabled()) { - log.info("--------------------------EventMeshTCPServer Shutdown"); + if (eventMeshTCPConfiguration.isEventMeshServerMetaStorageEnable()) { + eventMeshRebalanceService.shutdown(); + this.unRegister(); } + + log.info("--------------------------EventMeshTCPServer Shutdown"); } + /** + * Related to the registry module + * + * @return boolean + */ public boolean register() { boolean registerResult = false; try { @@ -306,11 +168,11 @@ public boolean register() { + EventMeshConstants.IP_PORT_SEPARATOR + eventMeshTCPConfiguration.getEventMeshTcpServerPort(); EventMeshRegisterInfo eventMeshRegisterInfo = new EventMeshRegisterInfo(); eventMeshRegisterInfo.setEventMeshClusterName(eventMeshTCPConfiguration.getEventMeshCluster()); - eventMeshRegisterInfo.setEventMeshName(eventMeshTCPConfiguration.getEventMeshName() + "-" + ConfigurationContextUtil.TCP); + eventMeshRegisterInfo.setEventMeshName(eventMeshTCPConfiguration.getEventMeshName() + "-" + TCP); eventMeshRegisterInfo.setEndPoint(endPoints); eventMeshRegisterInfo.setEventMeshInstanceNumMap(clientSessionGroupMapping.prepareProxyClientDistributionData()); - eventMeshRegisterInfo.setProtocolType(ConfigurationContextUtil.TCP); - registerResult = registry.register(eventMeshRegisterInfo); + eventMeshRegisterInfo.setProtocolType(TCP); + registerResult = metaStorage.register(eventMeshRegisterInfo); } catch (Exception e) { log.error("eventMesh register to registry failed", e); } @@ -318,75 +180,62 @@ public boolean register() { return registerResult; } - private void unRegister() throws Exception { + /** + * Related to the registry module + */ + private void unRegister() { String endPoints = IPUtils.getLocalAddress() + EventMeshConstants.IP_PORT_SEPARATOR + eventMeshTCPConfiguration.getEventMeshTcpServerPort(); EventMeshUnRegisterInfo eventMeshUnRegisterInfo = new EventMeshUnRegisterInfo(); eventMeshUnRegisterInfo.setEventMeshClusterName(eventMeshTCPConfiguration.getEventMeshCluster()); eventMeshUnRegisterInfo.setEventMeshName(eventMeshTCPConfiguration.getEventMeshName()); eventMeshUnRegisterInfo.setEndPoint(endPoints); - eventMeshUnRegisterInfo.setProtocolType(ConfigurationContextUtil.TCP); - boolean registerResult = registry.unRegister(eventMeshUnRegisterInfo); + eventMeshUnRegisterInfo.setProtocolType(TCP); + boolean registerResult = metaStorage.unRegister(eventMeshUnRegisterInfo); if (!registerResult) { throw new EventMeshException("eventMesh fail to unRegister"); } } - private void initThreadPool() throws Exception { - super.init("eventMesh-tcp"); + private void registerTCPRequestProcessor() { + ThreadPoolExecutor taskHandleExecutorService = super.getTcpThreadPoolGroup().getTaskHandleExecutorService(); - scheduler = ThreadPoolFactory.createScheduledExecutor(eventMeshTCPConfiguration.getEventMeshTcpGlobalScheduler(), - new EventMeshThreadFactory("eventMesh-tcp-scheduler", true)); + HelloProcessor helloProcessor = new HelloProcessor(this); + registerProcessor(Command.HELLO_REQUEST, helloProcessor, taskHandleExecutorService); - taskHandleExecutorService = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshTCPConfiguration.getEventMeshTcpTaskHandleExecutorPoolSize(), - eventMeshTCPConfiguration.getEventMeshTcpTaskHandleExecutorPoolSize(), - new LinkedBlockingQueue<>(10_000), - new EventMeshThreadFactory("eventMesh-tcp-task-handle", true)); + RecommendProcessor recommendProcessor = new RecommendProcessor(this); + registerProcessor(Command.RECOMMEND_REQUEST, recommendProcessor, taskHandleExecutorService); - broadcastMsgDownstreamExecutorService = ThreadPoolFactory.createThreadPoolExecutor( - eventMeshTCPConfiguration.getEventMeshTcpMsgDownStreamExecutorPoolSize(), - eventMeshTCPConfiguration.getEventMeshTcpMsgDownStreamExecutorPoolSize(), - new LinkedBlockingQueue<>(10_000), - new EventMeshThreadFactory("eventMesh-tcp-msg-downstream", true)); - } + HeartBeatProcessor heartBeatProcessor = new HeartBeatProcessor(this); + registerProcessor(Command.HEARTBEAT_REQUEST, heartBeatProcessor, taskHandleExecutorService); - private void shutdownThreadPool() { - scheduler.shutdown(); - taskHandleExecutorService.shutdown(); - } + GoodbyeProcessor goodbyeProcessor = new GoodbyeProcessor(this); + registerProcessor(Command.CLIENT_GOODBYE_REQUEST, goodbyeProcessor, taskHandleExecutorService); + registerProcessor(Command.SERVER_GOODBYE_RESPONSE, goodbyeProcessor, taskHandleExecutorService); - private GlobalTrafficShapingHandler newGTSHandler(final ScheduledExecutorService executor, final long readLimit) { - GlobalTrafficShapingHandler handler = new GlobalTrafficShapingHandler(executor, 0, readLimit) { - @Override - protected long calculateSize(final Object msg) { - return 1; - } - }; - handler.setMaxTimeWait(1_000); - return handler; - } + SubscribeProcessor subscribeProcessor = new SubscribeProcessor(this); + registerProcessor(Command.SUBSCRIBE_REQUEST, subscribeProcessor, taskHandleExecutorService); - private ChannelTrafficShapingHandler newCTSHandler(final long readLimit) { - ChannelTrafficShapingHandler handler = new ChannelTrafficShapingHandler(0, readLimit) { - @Override - protected long calculateSize(final Object msg) { - return 1; - } - }; - handler.setMaxTimeWait(3_000); - return handler; - } + UnSubscribeProcessor unSubscribeProcessor = new UnSubscribeProcessor(this); + registerProcessor(Command.UNSUBSCRIBE_REQUEST, unSubscribeProcessor, taskHandleExecutorService); - public ClientSessionGroupMapping getClientSessionGroupMapping() { - return clientSessionGroupMapping; - } + ListenProcessor listenProcessor = new ListenProcessor(this); + registerProcessor(Command.LISTEN_REQUEST, listenProcessor, taskHandleExecutorService); - public EventMeshTcpRetryer getEventMeshTcpRetryer() { - return eventMeshTcpRetryer; - } + ThreadPoolExecutor sendExecutorService = super.getTcpThreadPoolGroup().getSendExecutorService(); + MessageTransferProcessor messageTransferProcessor = new MessageTransferProcessor(this); + registerProcessor(Command.REQUEST_TO_SERVER, messageTransferProcessor, sendExecutorService); + registerProcessor(Command.ASYNC_MESSAGE_TO_SERVER, messageTransferProcessor, sendExecutorService); + registerProcessor(Command.BROADCAST_MESSAGE_TO_SERVER, messageTransferProcessor, sendExecutorService); + + ThreadPoolExecutor replyExecutorService = super.getTcpThreadPoolGroup().getReplyExecutorService(); + registerProcessor(Command.RESPONSE_TO_SERVER, messageTransferProcessor, replyExecutorService); - public EventMeshTcpMonitor getEventMeshTcpMonitor() { - return eventMeshTcpMonitor; + ThreadPoolExecutor ackExecutorService = super.getTcpThreadPoolGroup().getAckExecutorService(); + MessageAckProcessor messageAckProcessor = new MessageAckProcessor(this); + registerProcessor(Command.RESPONSE_TO_CLIENT_ACK, messageAckProcessor, ackExecutorService); + registerProcessor(Command.ASYNC_MESSAGE_TO_CLIENT_ACK, messageAckProcessor, ackExecutorService); + registerProcessor(Command.BROADCAST_MESSAGE_TO_CLIENT_ACK, messageAckProcessor, ackExecutorService); + registerProcessor(Command.REQUEST_TO_CLIENT_ACK, messageAckProcessor, ackExecutorService); } public EventMeshServer getEventMeshServer() { @@ -397,8 +246,8 @@ public EventMeshTCPConfiguration getEventMeshTCPConfiguration() { return eventMeshTCPConfiguration; } - public Registry getRegistry() { - return registry; + public MetaStorage getMetaStorage() { + return metaStorage; } public EventMeshRebalanceService getEventMeshRebalanceService() { @@ -417,7 +266,23 @@ public Acl getAcl() { return acl; } - public EventMeshTcpConnectionHandler getEventMeshTcpConnectionHandler() { - return eventMeshTcpConnectionHandler; + public ClientSessionGroupMapping getClientSessionGroupMapping() { + return clientSessionGroupMapping; + } + + public void setClientSessionGroupMapping(ClientSessionGroupMapping clientSessionGroupMapping) { + this.clientSessionGroupMapping = clientSessionGroupMapping; + } + + public RateLimiter getRateLimiter() { + return rateLimiter; + } + + public void setRateLimiter(RateLimiter rateLimiter) { + this.rateLimiter = rateLimiter; + } + + public TcpRetryer getTcpRetryer() { + return tcpRetryer; } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshTcpBootstrap.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshTcpBootstrap.java index b9514aed83..9cd665d28a 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshTcpBootstrap.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/EventMeshTcpBootstrap.java @@ -17,6 +17,8 @@ package org.apache.eventmesh.runtime.boot; +import static org.apache.eventmesh.common.Constants.TCP; + import org.apache.eventmesh.common.config.ConfigService; import org.apache.eventmesh.common.utils.ConfigurationContextUtil; import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; @@ -35,7 +37,7 @@ public EventMeshTcpBootstrap(EventMeshServer eventMeshServer) { ConfigService configService = ConfigService.getInstance(); this.eventMeshTcpConfiguration = configService.buildConfigInstance(EventMeshTCPConfiguration.class); - ConfigurationContextUtil.putIfAbsent(ConfigurationContextUtil.TCP, eventMeshTcpConfiguration); + ConfigurationContextUtil.putIfAbsent(TCP, eventMeshTcpConfiguration); } @Override diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/FilterEngine.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/FilterEngine.java new file mode 100644 index 0000000000..bf6eb9dadc --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/FilterEngine.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.boot; + +import org.apache.eventmesh.api.meta.MetaServiceListener; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.filter.pattern.Pattern; +import org.apache.eventmesh.filter.patternbuild.PatternBuilder; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.ConsumerGroupManager; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.ConsumerManager; +import org.apache.eventmesh.runtime.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.ProducerManager; +import org.apache.eventmesh.runtime.meta.MetaStorage; + +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import com.fasterxml.jackson.databind.JsonNode; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class FilterEngine { + + /** + * key:group-topic + **/ + private final Map filterPatternMap = new HashMap<>(); + + private final String filterPrefix = "filter-"; + + private final MetaStorage metaStorage; + + private MetaServiceListener metaServiceListener; + + private final ProducerManager producerManager; + + private final ConsumerManager consumerManager; + + private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + + public FilterEngine(MetaStorage metaStorage, ProducerManager producerManager, ConsumerManager consumerManager) { + this.metaStorage = metaStorage; + this.producerManager = producerManager; + this.consumerManager = consumerManager; + } + + public void start() { + Map filterMetaData = metaStorage.getMetaData(filterPrefix, true); + for (Entry filterDataEntry : filterMetaData.entrySet()) { + // filter-group + String key = filterDataEntry.getKey(); + // topic-filterRule list + String value = filterDataEntry.getValue(); + updateFilterPatternMap(key, value); + } + metaServiceListener = this::updateFilterPatternMap; + + // addListeners for producerManager & consumerManager + scheduledExecutorService.scheduleAtFixedRate(() -> { + ConcurrentHashMap producerMap = producerManager.getProducerTable(); + for (String producerGroup : producerMap.keySet()) { + for (String filterKey : filterPatternMap.keySet()) { + if (!StringUtils.contains(filterKey, producerGroup)) { + addFilterListener(producerGroup); + log.info("addFilterListener for producer group: " + producerGroup); + } + } + } + ConcurrentHashMap consumerMap = consumerManager.getClientTable(); + for (String consumerGroup : consumerMap.keySet()) { + for (String filterKey : filterPatternMap.keySet()) { + if (!StringUtils.contains(filterKey, consumerGroup)) { + addFilterListener(consumerGroup); + log.info("addFilterListener for consumer group: " + consumerGroup); + } + } + } + }, 10_000, 5_000, TimeUnit.MILLISECONDS); + } + + private void updateFilterPatternMap(String key, String value) { + String group = StringUtils.substringAfter(key, filterPrefix); + + JsonNode filterJsonNodeArray = JsonUtils.getJsonNode(value); + if (filterJsonNodeArray != null) { + for (JsonNode filterJsonNode : filterJsonNodeArray) { + String topic = filterJsonNode.get("topic").asText(); + String filterCondition = filterJsonNode.get("condition").toString(); + Pattern filterPattern = PatternBuilder.build(filterCondition); + filterPatternMap.put(group + "-" + topic, filterPattern); + } + } + addFilterListener(group); + } + + public void addFilterListener(String group) { + String filterKey = filterPrefix + group; + try { + metaStorage.getMetaDataWithListener(metaServiceListener, filterKey); + } catch (Exception e) { + throw new RuntimeException("addFilterListener exception", e); + } + } + + public void shutdown() { + scheduledExecutorService.shutdown(); + } + + public Pattern getFilterPattern(String key) { + return filterPatternMap.get(key); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/HTTPThreadPoolGroup.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/HTTPThreadPoolGroup.java new file mode 100644 index 0000000000..4c675a0f85 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/HTTPThreadPoolGroup.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.runtime.boot; + +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.runtime.configuration.EventMeshHTTPConfiguration; + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; + +public class HTTPThreadPoolGroup implements ThreadPoolGroup { + + private final EventMeshHTTPConfiguration eventMeshHttpConfiguration; + + private ThreadPoolExecutor batchMsgExecutor; + private ThreadPoolExecutor sendMsgExecutor; + private ThreadPoolExecutor remoteMsgExecutor; + private ThreadPoolExecutor replyMsgExecutor; + private ThreadPoolExecutor pushMsgExecutor; + private ThreadPoolExecutor clientManageExecutor; + private ThreadPoolExecutor runtimeAdminExecutor; + private ThreadPoolExecutor webhookExecutor; + + public HTTPThreadPoolGroup(EventMeshHTTPConfiguration eventMeshHttpConfiguration) { + this.eventMeshHttpConfiguration = eventMeshHttpConfiguration; + } + + @Override + public void initThreadPool() { + + batchMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshHttpConfiguration.getEventMeshServerBatchMsgThreadNum(), + eventMeshHttpConfiguration.getEventMeshServerBatchMsgThreadNum(), + new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerBatchBlockQSize()), + "eventMesh-batchMsg", true); + + sendMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshHttpConfiguration.getEventMeshServerSendMsgThreadNum(), + eventMeshHttpConfiguration.getEventMeshServerSendMsgThreadNum(), + new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerSendMsgBlockQSize()), + "eventMesh-sendMsg", true); + + remoteMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshHttpConfiguration.getEventMeshServerRemoteMsgThreadNum(), + eventMeshHttpConfiguration.getEventMeshServerRemoteMsgThreadNum(), + new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerRemoteMsgBlockQSize()), + "eventMesh-remoteMsg", true); + + pushMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshHttpConfiguration.getEventMeshServerPushMsgThreadNum(), + eventMeshHttpConfiguration.getEventMeshServerPushMsgThreadNum(), + new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerPushMsgBlockQSize()), + "eventMesh-pushMsg", true); + + clientManageExecutor = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshHttpConfiguration.getEventMeshServerClientManageThreadNum(), + eventMeshHttpConfiguration.getEventMeshServerClientManageThreadNum(), + new LinkedBlockingQueue<>(eventMeshHttpConfiguration.getEventMeshServerClientManageBlockQSize()), + "eventMesh-clientManage", true); + + // The runtimeAdminExecutor here is for the runtime.admin package and has nothing to do with the eventmesh-admin module. + runtimeAdminExecutor = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshHttpConfiguration.getEventMeshServerAdminThreadNum(), + eventMeshHttpConfiguration.getEventMeshServerAdminThreadNum(), + new LinkedBlockingQueue<>(50), "eventMesh-runtime-admin", true); + + replyMsgExecutor = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshHttpConfiguration.getEventMeshServerReplyMsgThreadNum(), + eventMeshHttpConfiguration.getEventMeshServerReplyMsgThreadNum(), + new LinkedBlockingQueue<>(100), + "eventMesh-replyMsg", true); + + webhookExecutor = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshHttpConfiguration.getEventMeshServerWebhookThreadNum(), + eventMeshHttpConfiguration.getEventMeshServerWebhookThreadNum(), + new LinkedBlockingQueue<>(100), "eventMesh-webhook", true); + } + + @Override + public void shutdownThreadPool() { + if (batchMsgExecutor != null) { + batchMsgExecutor.shutdown(); + } + if (runtimeAdminExecutor != null) { + runtimeAdminExecutor.shutdown(); + } + if (clientManageExecutor != null) { + clientManageExecutor.shutdown(); + } + if (sendMsgExecutor != null) { + sendMsgExecutor.shutdown(); + } + if (remoteMsgExecutor != null) { + remoteMsgExecutor.shutdown(); + } + if (pushMsgExecutor != null) { + pushMsgExecutor.shutdown(); + } + if (replyMsgExecutor != null) { + replyMsgExecutor.shutdown(); + } + } + + public ThreadPoolExecutor getBatchMsgExecutor() { + return batchMsgExecutor; + } + + public ThreadPoolExecutor getSendMsgExecutor() { + return sendMsgExecutor; + } + + public ThreadPoolExecutor getRemoteMsgExecutor() { + return remoteMsgExecutor; + } + + public ThreadPoolExecutor getReplyMsgExecutor() { + return replyMsgExecutor; + } + + public ThreadPoolExecutor getPushMsgExecutor() { + return pushMsgExecutor; + } + + public ThreadPoolExecutor getClientManageExecutor() { + return clientManageExecutor; + } + + public ThreadPoolExecutor getRuntimeAdminExecutor() { + return runtimeAdminExecutor; + } + + public ThreadPoolExecutor getWebhookExecutor() { + return webhookExecutor; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/RemotingServer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/RemotingServer.java new file mode 100644 index 0000000000..764075cc64 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/RemotingServer.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.runtime.boot; + +import org.apache.eventmesh.common.config.CommonConfiguration; + +/** + * Remoting server interface. + */ +public interface RemotingServer { + + void init() throws Exception; + + CommonConfiguration getConfiguration(); +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/TCPThreadPoolGroup.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/TCPThreadPoolGroup.java new file mode 100644 index 0000000000..5f71a57f55 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/TCPThreadPoolGroup.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.EventMeshThreadFactory; +import org.apache.eventmesh.common.ThreadPoolFactory; +import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ThreadPoolExecutor; + +public class TCPThreadPoolGroup implements ThreadPoolGroup { + + private final EventMeshTCPConfiguration eventMeshTCPConfiguration; + private ScheduledExecutorService scheduler; + private ThreadPoolExecutor taskHandleExecutorService; + private ThreadPoolExecutor sendExecutorService; + private ThreadPoolExecutor ackExecutorService; + private ThreadPoolExecutor replyExecutorService; + private ThreadPoolExecutor broadcastMsgDownstreamExecutorService; + + public TCPThreadPoolGroup(EventMeshTCPConfiguration eventMeshTCPConfiguration) { + this.eventMeshTCPConfiguration = eventMeshTCPConfiguration; + } + + @Override + public void initThreadPool() { + + scheduler = ThreadPoolFactory.createScheduledExecutor(eventMeshTCPConfiguration.getEventMeshTcpGlobalScheduler(), + new EventMeshThreadFactory("eventMesh-tcp-scheduler", true)); + + taskHandleExecutorService = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshTCPConfiguration.getEventMeshTcpTaskHandleExecutorPoolSize(), + eventMeshTCPConfiguration.getEventMeshTcpTaskHandleExecutorPoolSize(), + new LinkedBlockingQueue<>(eventMeshTCPConfiguration.getEventMeshTcpTaskHandleExecutorQueueSize()), + new EventMeshThreadFactory("eventMesh-tcp-task-handle", true)); + + sendExecutorService = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshTCPConfiguration.getEventMeshTcpMsgSendExecutorPoolSize(), + eventMeshTCPConfiguration.getEventMeshTcpMsgSendExecutorPoolSize(), + new LinkedBlockingQueue<>(eventMeshTCPConfiguration.getEventMeshTcpMsgSendExecutorQueueSize()), + new EventMeshThreadFactory("eventMesh-tcp-msg-send", true)); + + replyExecutorService = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshTCPConfiguration.getEventMeshTcpMsgReplyExecutorPoolSize(), + eventMeshTCPConfiguration.getEventMeshTcpMsgReplyExecutorPoolSize(), + new LinkedBlockingQueue<>(eventMeshTCPConfiguration.getEventMeshTcpMsgReplyExecutorQueueSize()), + new EventMeshThreadFactory("eventMesh-tcp-msg-reply", true)); + + ackExecutorService = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshTCPConfiguration.getEventMeshTcpMsgAckExecutorPoolSize(), + eventMeshTCPConfiguration.getEventMeshTcpMsgAckExecutorPoolSize(), + new LinkedBlockingQueue<>(eventMeshTCPConfiguration.getEventMeshTcpMsgAckExecutorQueueSize()), + new EventMeshThreadFactory("eventMesh-tcp-msg-ack", true)); + + broadcastMsgDownstreamExecutorService = ThreadPoolFactory.createThreadPoolExecutor( + eventMeshTCPConfiguration.getEventMeshTcpMsgDownStreamExecutorPoolSize(), + eventMeshTCPConfiguration.getEventMeshTcpMsgDownStreamExecutorPoolSize(), + new LinkedBlockingQueue<>(10_000), + new EventMeshThreadFactory("eventMesh-tcp-msg-downstream", true)); + } + + @Override + public void shutdownThreadPool() { + scheduler.shutdown(); + taskHandleExecutorService.shutdown(); + sendExecutorService.shutdown();; + replyExecutorService.shutdown(); + ackExecutorService.shutdown(); + broadcastMsgDownstreamExecutorService.shutdown(); + } + + public ScheduledExecutorService getScheduler() { + return scheduler; + } + + public ThreadPoolExecutor getTaskHandleExecutorService() { + return taskHandleExecutorService; + } + + public ThreadPoolExecutor getBroadcastMsgDownstreamExecutorService() { + return broadcastMsgDownstreamExecutorService; + } + + public ThreadPoolExecutor getSendExecutorService() { + return sendExecutorService; + } + + public ThreadPoolExecutor getAckExecutorService() { + return ackExecutorService; + } + + public ThreadPoolExecutor getReplyExecutorService() { + return replyExecutorService; + } +} \ No newline at end of file diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/ThreadPoolGroup.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/ThreadPoolGroup.java new file mode 100644 index 0000000000..412094e6e9 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/ThreadPoolGroup.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.boot; + +/** + * The implementation class for this interface is used to assemble the thread pool required by the server + * + */ +public interface ThreadPoolGroup { + + void initThreadPool(); + + void shutdownThreadPool(); +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/TransformerEngine.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/TransformerEngine.java new file mode 100644 index 0000000000..551bcb2799 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/boot/TransformerEngine.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.boot; + +import org.apache.eventmesh.api.meta.MetaServiceListener; +import org.apache.eventmesh.common.utils.JsonUtils; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.ConsumerGroupManager; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.ConsumerManager; +import org.apache.eventmesh.runtime.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.ProducerManager; +import org.apache.eventmesh.runtime.meta.MetaStorage; +import org.apache.eventmesh.transformer.Transformer; +import org.apache.eventmesh.transformer.TransformerBuilder; +import org.apache.eventmesh.transformer.TransformerParam; + +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import com.fasterxml.jackson.databind.JsonNode; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class TransformerEngine { + + /** + * key:group-topic + **/ + private final Map transformerMap = new HashMap<>(); + + private final String transformerPrefix = "transformer-"; + + private final MetaStorage metaStorage; + + private MetaServiceListener metaServiceListener; + + private final ProducerManager producerManager; + + private final ConsumerManager consumerManager; + + private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + + public TransformerEngine(MetaStorage metaStorage, ProducerManager producerManager, ConsumerManager consumerManager) { + this.metaStorage = metaStorage; + this.producerManager = producerManager; + this.consumerManager = consumerManager; + } + + public void start() { + Map transformerMetaData = metaStorage.getMetaData(transformerPrefix, true); + for (Entry transformerDataEntry : transformerMetaData.entrySet()) { + // transformer-group + String key = transformerDataEntry.getKey(); + // topic-transformerParam list + String value = transformerDataEntry.getValue(); + updateTransformerMap(key, value); + } + metaServiceListener = this::updateTransformerMap; + + // addListeners for producerManager & consumerManager + scheduledExecutorService.scheduleAtFixedRate(() -> { + ConcurrentHashMap producerMap = producerManager.getProducerTable(); + for (String producerGroup : producerMap.keySet()) { + for (String transformerKey : transformerMap.keySet()) { + if (!StringUtils.contains(transformerKey, producerGroup)) { + addTransformerListener(producerGroup); + log.info("addTransformerListener for producer group: " + producerGroup); + } + } + } + ConcurrentHashMap consumerMap = consumerManager.getClientTable(); + for (String consumerGroup : consumerMap.keySet()) { + for (String transformerKey : transformerMap.keySet()) { + if (!StringUtils.contains(transformerKey, consumerGroup)) { + addTransformerListener(consumerGroup); + log.info("addTransformerListener for consumer group: " + consumerGroup); + } + } + } + }, 10_000, 5_000, TimeUnit.MILLISECONDS); + } + + private void updateTransformerMap(String key, String value) { + String group = StringUtils.substringAfter(key, transformerPrefix); + + JsonNode transformerJsonNodeArray = JsonUtils.getJsonNode(value); + + if (transformerJsonNodeArray != null) { + for (JsonNode transformerJsonNode : transformerJsonNodeArray) { + String topic = transformerJsonNode.get("topic").asText(); + String transformerParam = transformerJsonNode.get("transformerParam").toString(); + TransformerParam tfp = JsonUtils.parseObject(transformerParam, TransformerParam.class); + Transformer transformer = TransformerBuilder.buildTransformer(tfp); + transformerMap.put(group + "-" + topic, transformer); + } + } + addTransformerListener(group); + } + + public void addTransformerListener(String group) { + String transformerKey = transformerPrefix + group; + try { + metaStorage.getMetaDataWithListener(metaServiceListener, transformerKey); + } catch (Exception e) { + throw new RuntimeException("addTransformerListener exception", e); + } + } + + public void shutdown() { + scheduledExecutorService.shutdown(); + } + + public Transformer getTransformer(String key) { + return transformerMap.get(key); + } + +} 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 index 893e190356..ddab176557 100644 --- 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 @@ -43,4 +43,3 @@ public void setObject2(T2 object2) { this.object2 = object2; } } - 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 index 6dc688479d..eee723aaa1 100644 --- 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 @@ -56,8 +56,8 @@ public class EventMeshGrpcConfiguration extends CommonConfiguration { @ConfigFiled(field = "clientmanage.threads.num") private int eventMeshServerSubscribeMsgThreadNum = 4; - @ConfigFiled(field = "registry.threads.num") - private int eventMeshServerRegistryThreadNum = 10; + @ConfigFiled(field = "metaStorage.threads.num") + private int eventMeshServerMetaStorageThreadNum = 10; @ConfigFiled(field = "admin.threads.num") private int eventMeshServerAdminThreadNum = 2; @@ -65,8 +65,8 @@ public class EventMeshGrpcConfiguration extends CommonConfiguration { @ConfigFiled(field = "retry.threads.num") private int eventMeshServerRetryThreadNum = 2; - @ConfigFiled(field = "pull.registry.interval") - private int eventMeshServerPullRegistryInterval = 30000; + @ConfigFiled(field = "pull.metaStorage.interval") + private int eventMeshServerPullMetaStorageInterval = 30000; @ConfigFiled(field = "async.accumulation.threshold") private int eventMeshServerAsyncAccumulationThreshold = 1000; 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 index a36df0d8e4..a7ed9b26fe 100644 --- 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 @@ -60,8 +60,8 @@ public class EventMeshHTTPConfiguration extends CommonConfiguration { @ConfigFiled(field = "clientmanage.threads.num") private int eventMeshServerClientManageThreadNum = 4; - @ConfigFiled(field = "registry.threads.num") - private int eventMeshServerRegistryThreadNum = 10; + @ConfigFiled(field = "metaStorage.threads.num") + private int eventMeshServerMetaStorageThreadNum = 10; @ConfigFiled(field = "admin.threads.num") private int eventMeshServerAdminThreadNum = 2; @@ -72,8 +72,8 @@ public class EventMeshHTTPConfiguration extends CommonConfiguration { @ConfigFiled(field = "") private int eventMeshServerWebhookThreadNum = 4; - @ConfigFiled(field = "pull.registry.interval") - private int eventMeshServerPullRegistryInterval = 30000; + @ConfigFiled(field = "pull.metaStorage.interval") + private int eventMeshServerPullMetaStorageInterval = 30000; @ConfigFiled(field = "async.accumulation.threshold") private int eventMeshServerAsyncAccumulationThreshold = 1000; @@ -131,4 +131,5 @@ public class EventMeshHTTPConfiguration extends CommonConfiguration { @ConfigFiled(field = "blacklist.ipv6") private List eventMeshIpv6BlackList = Collections.emptyList(); + } 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 index 1133445401..84871b582c 100644 --- 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 @@ -53,13 +53,34 @@ public class EventMeshTCPConfiguration extends CommonConfiguration { @ConfigFiled(field = "tcp.clientMaxNum") private int eventMeshTcpClientMaxNum = 10000; - //======================================= New add config ================================= + // ======================================= New add config ================================= @ConfigFiled(field = "global.scheduler") private int eventMeshTcpGlobalScheduler = 5; @ConfigFiled(field = "tcp.taskHandleExecutorPoolSize") - private int eventMeshTcpTaskHandleExecutorPoolSize = Runtime.getRuntime().availableProcessors(); + private int eventMeshTcpTaskHandleExecutorPoolSize = 2 * Runtime.getRuntime().availableProcessors(); + + @ConfigFiled(field = "tcp.sendExecutorPoolSize") + private int eventMeshTcpMsgSendExecutorPoolSize = 2 * Runtime.getRuntime().availableProcessors(); + + @ConfigFiled(field = "tcp.replyExecutorPoolSize") + private int eventMeshTcpMsgReplyExecutorPoolSize = 2 * Runtime.getRuntime().availableProcessors(); + + @ConfigFiled(field = "tcp.ackExecutorPoolSize") + private int eventMeshTcpMsgAckExecutorPoolSize = 2 * Runtime.getRuntime().availableProcessors(); + + @ConfigFiled(field = "tcp.taskHandleExecutorQueueSize") + private int eventMeshTcpTaskHandleExecutorQueueSize = 10000; + + @ConfigFiled(field = "tcp.sendExecutorQueueSize") + private int eventMeshTcpMsgSendExecutorQueueSize = 10000; + + @ConfigFiled(field = "tcp.replyExecutorQueueSize") + private int eventMeshTcpMsgReplyExecutorQueueSize = 10000; + + @ConfigFiled(field = "tcp.ackExecutorQueueSize") + private int eventMeshTcpMsgAckExecutorQueueSize = 10000; @ConfigFiled(field = "tcp.msgDownStreamExecutorPoolSize") private int eventMeshTcpMsgDownStreamExecutorPoolSize = Math.max(Runtime.getRuntime().availableProcessors(), 8); 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 index 6ffa05b71d..4196572ccb 100644 --- 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 @@ -66,7 +66,7 @@ public class EventMeshConstants { public static final String REQ_IDC = "req0idc"; public static final String REQ_GROUP = "req0group"; - //default TTL 4 hours + // default TTL 4 hours public static final Integer DEFAULT_MSG_TTL_MILLS = 14400000; public static final int DEFAULT_TIMEOUT_IN_MILLISECONDS = 3000; @@ -86,7 +86,6 @@ public class EventMeshConstants { 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"; @@ -109,7 +108,7 @@ public class EventMeshConstants { public static final String MANAGE_PURPOSE = "purpose"; public static final String MANAGE_TOPIC = "topic"; public static final String MANAGE_MSG = "msg"; - public static final String EVENTMESH_SEND_BACK_TIMES = "eventmeshdendbacktimes"; + public static final String EVENTMESH_SEND_BACK_TIMES = "eventmeshsendbacktimes"; public static final String EVENTMESH_SEND_BACK_IP = "eventmeshsendbackip"; @@ -125,11 +124,11 @@ public class EventMeshConstants { 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_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 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"; public static final String PRODUCER_GROUP = "producerGroup"; @@ -153,6 +152,9 @@ public class EventMeshConstants { public static final String MESSAGE = "message"; public static final String CMD = "cmd"; public static final String ACL = "acl"; + public static final String BATCH_MSG = "batchMessage"; + public static final String TCP_MONITOR = "tcpMonitor"; + public static final String APP_MONITOR = "appMonitor"; public static final String MSG_TYPE = "msgtype"; public static final String PERSISTENT = "persistent"; public static final String HANDLER_ORIGIN = "Access-Control-Allow-Origin"; diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumer/SubscriptionManager.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumer/SubscriptionManager.java index 37ac2719e1..155869772b 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumer/SubscriptionManager.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/consumer/SubscriptionManager.java @@ -17,28 +17,49 @@ package org.apache.eventmesh.runtime.core.consumer; +import org.apache.eventmesh.api.meta.config.EventMeshMetaConfig; import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.utils.JsonUtils; 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.core.protocol.http.processor.inf.Client; +import org.apache.eventmesh.runtime.meta.MetaStorage; 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.List; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import lombok.extern.slf4j.Slf4j; @Slf4j public class SubscriptionManager { - private final ConcurrentHashMap localConsumerGroupMapping = new ConcurrentHashMap<>(64); + private final boolean isEventMeshServerMetaStorageEnable; + + private final MetaStorage metaStorage; - private final ConcurrentHashMap> localClientInfoMapping = new ConcurrentHashMap<>(64); + /** + * key: group + */ + private final ConcurrentHashMap localConsumerGroupMapping = new ConcurrentHashMap<>(64); + + /** + * key: group@topic + */ + private final ConcurrentHashMap> localClientInfoMapping = new ConcurrentHashMap<>(64); + + public SubscriptionManager(boolean isEventMeshServerMetaStorageEnable, MetaStorage metaStorage) { + this.isEventMeshServerMetaStorageEnable = isEventMeshServerMetaStorageEnable; + this.metaStorage = metaStorage; + } public ConcurrentHashMap getLocalConsumerGroupMapping() { return localConsumerGroupMapping; @@ -62,7 +83,7 @@ public void registerClient(final ClientInfo clientInfo, final String consumerGro boolean isContains = false; for (final Client localClient : localClients) { - //TODO: compare the whole Client would be better? + // TODO: compare the whole Client would be better? if (StringUtils.equals(localClient.getUrl(), url)) { isContains = true; localClient.setLastUpTime(new Date()); @@ -124,8 +145,47 @@ public void updateSubscription(ClientInfo clientInfo, String consumerGroup, if (!consumerGroupTopicConf.getIdcUrls().containsKey(clientInfo.getIdc())) { consumerGroupTopicConf.getIdcUrls().putIfAbsent(clientInfo.getIdc(), new ArrayList<>()); } - //TODO: idcUrl list is not thread-safe + // TODO: idcUrl list is not thread-safe consumerGroupTopicConf.getIdcUrls().get(clientInfo.getIdc()).add(url); } } + + public void updateMetaData() { + if (!isEventMeshServerMetaStorageEnable) { + return; + } + try { + Map metadata = new HashMap<>(1 << 4); + for (Map.Entry consumerGroupMap : getLocalConsumerGroupMapping().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.toJSONString(consumerGroupMetadata)); + } + metadata.put(EventMeshMetaConfig.EVENT_MESH_PROTO, "http"); + + metaStorage.updateMetaData(metadata); + + } catch (Exception e) { + log.error("update eventmesh metadata error", e); + } + } } 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 index 9f714197c8..3e01eac9d1 100644 --- 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 @@ -24,11 +24,11 @@ public class ConsumerGroupConf implements Serializable { - //eg . 5013-1A0 + // eg . 5013-1A0 private String consumerGroup; - private final ConcurrentHashMap consumerGroupTopicConf - = new ConcurrentHashMap(); + private final ConcurrentHashMap consumerGroupTopicConf = + new ConcurrentHashMap(); public ConsumerGroupConf(String consumerGroup) { this.consumerGroup = consumerGroup; 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 index 2644ccd411..4c24605039 100644 --- 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 @@ -33,7 +33,6 @@ public class ConsumerGroupMetadata { */ private Map consumerGroupTopicMetadataMap = Maps.newConcurrentMap(); - public String getConsumerGroup() { return consumerGroup; } 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 index 8be4a45c9f..8e19d91de0 100644 --- 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 @@ -19,7 +19,6 @@ import java.util.Set; - import com.google.common.collect.Sets; public class ConsumerGroupTopicMetadata { @@ -39,7 +38,6 @@ public class ConsumerGroupTopicMetadata { */ private Set urls = Sets.newConcurrentHashSet(); - public String getConsumerGroup() { return consumerGroup; } 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 index 99ace0e5f3..9b5e7c827f 100644 --- 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 @@ -39,7 +39,6 @@ public String toString() { return sb.toString(); } - public enum ConsumerGroupStateAction { NEW, CHANGE, diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQAdminWrapper.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQAdminWrapper.java index bef3cbf4a5..7676c426ce 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQAdminWrapper.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/plugin/MQAdminWrapper.java @@ -26,7 +26,6 @@ import io.cloudevents.CloudEvent; - import lombok.extern.slf4j.Slf4j; @Slf4j 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 index 420a6b27cd..b9971e264f 100644 --- 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 @@ -27,7 +27,6 @@ import io.cloudevents.CloudEvent; - import lombok.extern.slf4j.Slf4j; @Slf4j 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 index 7b64e8281f..f0a50dcc05 100644 --- 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 @@ -26,7 +26,6 @@ import io.cloudevents.CloudEvent; - import lombok.extern.slf4j.Slf4j; @Slf4j diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/DelayRetryable.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/DelayRetryable.java deleted file mode 100644 index b60876a645..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/DelayRetryable.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 org.apache.eventmesh.runtime.core.protocol; - -import java.util.concurrent.Delayed; - -/** - * Retry - */ -public interface DelayRetryable extends Delayed { - - void retry() throws Exception; -} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/RetryContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/RetryContext.java index 939ef40ddd..ca796dc330 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/RetryContext.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/RetryContext.java @@ -17,14 +17,30 @@ package org.apache.eventmesh.runtime.core.protocol; -import java.util.concurrent.Delayed; -import java.util.concurrent.TimeUnit; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.retry.api.conf.RetryConfiguration; +import org.apache.eventmesh.retry.api.strategy.RetryStrategy; +import org.apache.eventmesh.retry.api.timer.TimerTask; +import org.apache.eventmesh.runtime.core.protocol.consumer.HandleMessageContext; +import org.apache.eventmesh.runtime.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.ProducerManager; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; -import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; import io.cloudevents.CloudEvent; -public abstract class RetryContext implements DelayRetryable { +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class RetryContext implements TimerTask { + + private static final Set RETRY_STRATEGY_PROCESSED_EVENT_LIST = Collections.synchronizedSet(new HashSet<>()); public CloudEvent event; @@ -32,22 +48,67 @@ public abstract class RetryContext implements DelayRetryable { public int retryTimes; + public CommonConfiguration commonConfiguration; + public long executeTime = System.currentTimeMillis(); - public RetryContext delay(long delay) { - this.executeTime = System.currentTimeMillis() + (retryTimes + 1) * delay; - return this; + public void setEvent(CloudEvent event) { + this.event = event; } @Override - public int compareTo(@Nonnull Delayed delayed) { - RetryContext obj = (RetryContext) delayed; - return Long.compare(this.executeTime, obj.executeTime); - + public void setExecuteTimeHook(long executeTime) { + this.executeTime = executeTime; } @Override - public long getDelay(TimeUnit unit) { - return unit.convert(this.executeTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); + public final void run() throws Exception { + String eventMeshRetryPluginType = Optional.ofNullable(commonConfiguration.getEventMeshRetryPluginType()) + .orElse(Constants.DEFAULT); + if (Constants.DEFAULT.equals(eventMeshRetryPluginType)) { + log.warn("Because eventmesh retry plugin is default, retry in memory."); + doRun(); + return; + } + if (!eventMeshRetryPluginType.equals(commonConfiguration.getEventMeshStoragePluginType())) { + log.warn("Because eventmesh retry plugin type mismatched with storage plugin type, retry in memory."); + doRun(); + return; + } + Optional retryStrategy = Optional.ofNullable( + EventMeshExtensionFactory.getExtension(RetryStrategy.class, + commonConfiguration.getEventMeshRetryPluginType())); + if (!retryStrategy.isPresent()) { + log.warn("Storage retry SPI not found, retry in memory."); + doRun(); + return; + } + if (!RETRY_STRATEGY_PROCESSED_EVENT_LIST.contains(event.getId())) { + String consumerGroupName = getHandleMessageContext().getConsumerGroup(); + EventMeshProducer producer = getProducerManager().getEventMeshProducer(consumerGroupName); + RetryConfiguration retryConfiguration = RetryConfiguration.builder() + .event(event) + .consumerGroupName(consumerGroupName) + .producer(producer.getMqProducerWrapper().getMeshMQProducer()) + .topic(getHandleMessageContext().getTopic()) + .build(); + retryStrategy.get().retry(retryConfiguration); + RETRY_STRATEGY_PROCESSED_EVENT_LIST.add(event.getId()); + } else { + RETRY_STRATEGY_PROCESSED_EVENT_LIST.remove(event.getId()); + getHandleMessageContext().finish(); + } + } + + protected HandleMessageContext getHandleMessageContext() throws Exception { + throw new IllegalAccessException("method not supported."); } + + public abstract void doRun() throws Exception; + + @SneakyThrows + protected ProducerManager getProducerManager() { + throw new IllegalAccessException("method not supported."); + } + } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/consumer/HandleMessageContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/consumer/HandleMessageContext.java new file mode 100644 index 0000000000..6ba20f3768 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/consumer/HandleMessageContext.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.runtime.core.protocol.consumer; + +/** + * Handle message context + */ +public interface HandleMessageContext { + + void finish(); + + String getTopic(); + + String getConsumerGroup(); +} 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 index 4fd701e929..b29e03b88c 100644 --- 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 @@ -17,12 +17,12 @@ 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.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; 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; @@ -31,7 +31,6 @@ 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; @@ -41,21 +40,20 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; - import lombok.extern.slf4j.Slf4j; @Slf4j public class ConsumerManager { - private final transient EventMeshGrpcServer eventMeshGrpcServer; + private final EventMeshGrpcServer eventMeshGrpcServer; - private final transient ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); // key: ConsumerGroup - private final transient Map> clientTable = new ConcurrentHashMap<>(); + private final Map> clientTable = new ConcurrentHashMap<>(); // key: ConsumerGroup - private final transient Map consumerTable = new ConcurrentHashMap<>(); + private final Map consumerTable = new ConcurrentHashMap<>(); public ConsumerManager(final EventMeshGrpcServer eventMeshGrpcServer) { this.eventMeshGrpcServer = eventMeshGrpcServer; @@ -66,16 +64,12 @@ public Map> getClientTable() { } public void init() throws Exception { - if (log.isInfoEnabled()) { - log.info("Grpc ConsumerManager initialized."); - } + log.info("Grpc ConsumerManager initialized."); } public void start() throws Exception { startClientCheck(); - if (log.isInfoEnabled()) { - log.info("Grpc ConsumerManager started."); - } + log.info("Grpc ConsumerManager started."); } public void shutdown() throws Exception { @@ -83,14 +77,11 @@ public void shutdown() throws Exception { consumer.shutdown(); } scheduledExecutorService.shutdown(); - if (log.isInfoEnabled()) { - log.info("Grpc ConsumerManager shutdown."); - } + log.info("Grpc ConsumerManager shutdown."); } public EventMeshConsumer getEventMeshConsumer(final String consumerGroup) { - return consumerTable.computeIfAbsent(consumerGroup, key -> - consumerTable.put(consumerGroup, new EventMeshConsumer(eventMeshGrpcServer, consumerGroup))); + return consumerTable.computeIfAbsent(consumerGroup, key -> new EventMeshConsumer(eventMeshGrpcServer, consumerGroup)); } public synchronized void registerClient(final ConsumerGroupClient newClient) { @@ -206,18 +197,12 @@ private void startClientCheck() { final int clientTimeout = eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshSessionExpiredInMills(); if (clientTimeout > 0) { scheduledExecutorService.scheduleAtFixedRate(() -> { - if (log.isDebugEnabled()) { - log.debug("grpc client info check"); - } + log.debug("grpc client info check"); - final List clientList = new LinkedList<>(); - clientTable.values().forEach(clients -> { - clientList.addAll(clients); - }); + final List clientList = new ArrayList<>(); + clientTable.values().forEach(clientList::addAll); - if (log.isDebugEnabled()) { - log.debug("total number of ConsumerGroupClients: {}", clientList.size()); - } + log.debug("total number of ConsumerGroupClients: {}", clientList.size()); if (CollectionUtils.isEmpty(clientList)) { return; @@ -226,10 +211,8 @@ private void startClientCheck() { final Set consumerGroupRestart = new HashSet<>(); clientList.forEach(client -> { if (System.currentTimeMillis() - client.getLastUpTime().getTime() > clientTimeout) { - if (log.isWarnEnabled()) { - log.warn("client {} lastUpdate time {} over three heartbeat cycles. Removing it", - JsonUtils.toJSONString(client), client.getLastUpTime()); - } + log.warn("client {} lastUpdate time {} over three heartbeat cycles. Removing it", + JsonUtils.toJSONString(client), client.getLastUpTime()); deregisterClient(client); if (getEventMeshConsumer(client.getConsumerGroup()).deregisterClient(client)) { @@ -243,9 +226,7 @@ private void startClientCheck() { try { restartEventMeshConsumer(consumerGroup); } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("Error in restarting EventMeshConsumer [{}]", consumerGroup, e); - } + log.error("Error in restarting EventMeshConsumer [{}]", consumerGroup, e); } }); }, 10_000, 10_000, TimeUnit.MILLISECONDS); 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 index f5e7b0037b..6f677ab4a4 100644 --- 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 @@ -22,7 +22,6 @@ import static org.apache.eventmesh.runtime.constants.EventMeshConstants.INSTANCE_NAME; import static org.apache.eventmesh.runtime.constants.EventMeshConstants.IS_BROADCAST; - import org.apache.eventmesh.api.AbstractContext; import org.apache.eventmesh.api.EventListener; import org.apache.eventmesh.api.EventMeshAction; @@ -30,29 +29,39 @@ import org.apache.eventmesh.api.SendCallback; import org.apache.eventmesh.api.SendResult; import org.apache.eventmesh.api.exception.OnExceptionContext; +import org.apache.eventmesh.api.meta.config.EventMeshMetaConfig; 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.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; +import org.apache.eventmesh.common.utils.JsonUtils; import org.apache.eventmesh.common.utils.ThreadUtils; 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.consumergroup.ConsumerGroupMetadata; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicMetadata; 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.producer.EventMeshProducer; -import org.apache.eventmesh.runtime.core.protocol.grpc.producer.SendMessageContext; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.StreamTopicConfig; +import org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup.WebhookTopicConfig; 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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; import org.apache.eventmesh.runtime.util.EventMeshUtil; import org.apache.commons.collections4.MapUtils; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Properties; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -64,24 +73,24 @@ @Slf4j public class EventMeshConsumer { - private final transient String consumerGroup; + private final String consumerGroup; - private final transient EventMeshGrpcServer eventMeshGrpcServer; + private final EventMeshGrpcServer eventMeshGrpcServer; - private final transient EventMeshGrpcConfiguration eventMeshGrpcConfiguration; + private final EventMeshGrpcConfiguration eventMeshGrpcConfiguration; - private final transient MQConsumerWrapper persistentMqConsumer; + private final MQConsumerWrapper persistentMqConsumer; - private final transient MQConsumerWrapper broadcastMqConsumer; + private final MQConsumerWrapper broadcastMqConsumer; - private final transient MessageHandler messageHandler; + private final MessageHandler messageHandler; - private transient ServiceState serviceState; + private ServiceState serviceState; /** * Key: topic Value: ConsumerGroupTopicConfig **/ - private final transient Map consumerGroupTopicConfig = new ConcurrentHashMap<>(); + private final Map consumerGroupTopicConfig = new ConcurrentHashMap<>(); public EventMeshConsumer(final EventMeshGrpcServer eventMeshGrpcServer, final String consumerGroup) { this.eventMeshGrpcServer = eventMeshGrpcServer; @@ -109,7 +118,7 @@ public synchronized boolean registerClient(final ConsumerGroupClient client) { requireRestart = true; } topicConfig.registerClient(client); - + updateMetaData(); return requireRestart; } @@ -130,10 +139,61 @@ public synchronized boolean deregisterClient(final ConsumerGroupClient client) { requireRestart = true; } } - + updateMetaData(); return requireRestart; } + public void updateMetaData() { + if (!eventMeshGrpcConfiguration.isEventMeshServerMetaStorageEnable()) { + return; + } + try { + Map metadata = new HashMap<>(1 << 4); + for (Map.Entry consumerGroupMap : consumerGroupTopicConfig.entrySet()) { + String topic = consumerGroupMap.getKey(); + + ConsumerGroupTopicConfig cgtConfig = consumerGroupMap.getValue(); + + GrpcType grpcType = cgtConfig.getGrpcType(); + String consumerGroupKey = cgtConfig.getConsumerGroup(); + ConsumerGroupMetadata consumerGroupMetadata = new ConsumerGroupMetadata(); + Map consumerGroupTopicMetadataMap = + new HashMap<>(1 << 4); + consumerGroupMetadata.setConsumerGroup(consumerGroupKey); + if (GrpcType.STREAM == grpcType) { + StreamTopicConfig streamTopicConfig = (StreamTopicConfig) cgtConfig; + ConsumerGroupTopicMetadata consumerGroupTopicMetadata = new ConsumerGroupTopicMetadata(); + consumerGroupTopicMetadata.setConsumerGroup(streamTopicConfig.getConsumerGroup()); + consumerGroupTopicMetadata.setTopic(streamTopicConfig.getTopic()); + Set clientSet = new HashSet<>(); + streamTopicConfig.getIdcEmitterMap().values().forEach(stringEmitterMap -> { + clientSet.addAll(stringEmitterMap.keySet()); + }); + + consumerGroupTopicMetadata.setUrls(clientSet); + consumerGroupTopicMetadataMap.put(topic, consumerGroupTopicMetadata); + } else { + WebhookTopicConfig webhookTopicConfig = (WebhookTopicConfig) cgtConfig; + ConsumerGroupTopicMetadata consumerGroupTopicMetadata = new ConsumerGroupTopicMetadata(); + consumerGroupTopicMetadata.setConsumerGroup(webhookTopicConfig.getConsumerGroup()); + consumerGroupTopicMetadata.setTopic(webhookTopicConfig.getTopic()); + Set set = new HashSet<>(webhookTopicConfig.getTotalUrls()); + consumerGroupTopicMetadata.setUrls(set); + consumerGroupTopicMetadataMap.put(topic, consumerGroupTopicMetadata); + } + + consumerGroupMetadata.setConsumerGroupTopicMetadataMap(consumerGroupTopicMetadataMap); + metadata.put(consumerGroupKey, JsonUtils.toJSONString(consumerGroupMetadata)); + } + metadata.put(EventMeshMetaConfig.EVENT_MESH_PROTO, "grpc"); + + eventMeshGrpcServer.getMetaStorage().updateMetaData(metadata); + + } catch (Exception e) { + log.error("update eventmesh metadata error", e); + } + } + public synchronized void init() throws Exception { if (MapUtils.isEmpty(consumerGroupTopicConfig)) { // no topics, don't init the consumer @@ -159,9 +219,7 @@ public synchronized void init() throws Exception { broadcastMqConsumer.registerEventListener(createEventListener(SubscriptionMode.BROADCASTING)); serviceState = ServiceState.INITED; - if (log.isInfoEnabled()) { - log.info("EventMeshConsumer [{}] initialized.............", consumerGroup); - } + log.info("EventMeshConsumer [{}] initialized.............", consumerGroup); } public synchronized void start() throws Exception { @@ -182,9 +240,7 @@ public synchronized void start() throws Exception { broadcastMqConsumer.start(); serviceState = ServiceState.RUNNING; - if (log.isInfoEnabled()) { - log.info("EventMeshConsumer [{}] started..........", consumerGroup); - } + log.info("EventMeshConsumer [{}] started..........", consumerGroup); } public synchronized void shutdown() throws Exception { @@ -192,9 +248,7 @@ public synchronized void shutdown() throws Exception { broadcastMqConsumer.shutdown(); serviceState = ServiceState.STOPPED; - if (log.isInfoEnabled()) { - log.info("EventMeshConsumer [{}] shutdown.........", consumerGroup); - } + log.info("EventMeshConsumer [{}] shutdown.........", consumerGroup); } public ServiceState getStatus() { @@ -202,36 +256,44 @@ public ServiceState getStatus() { } public void subscribe(final String topic, final SubscriptionMode subscriptionMode) throws Exception { - if (SubscriptionMode.CLUSTERING == subscriptionMode) { - persistentMqConsumer.subscribe(topic); - } else if (SubscriptionMode.BROADCASTING == subscriptionMode) { - broadcastMqConsumer.subscribe(topic); - } else { - //log.error("Subscribe Failed. Incorrect Subscription Mode"); - throw new Exception("Subscribe Failed. Incorrect Subscription Mode"); + switch (subscriptionMode) { + case CLUSTERING: + persistentMqConsumer.subscribe(topic); + break; + case BROADCASTING: + broadcastMqConsumer.subscribe(topic); + break; + default: + throw new Exception("Subscribe Failed. Incorrect Subscription Mode"); } } - public void unsubscribe(final Subscription.SubscriptionItem subscriptionItem) throws Exception { + public void unsubscribe(final SubscriptionItem subscriptionItem) throws Exception { final SubscriptionMode mode = subscriptionItem.getMode(); final String topic = subscriptionItem.getTopic(); - if (SubscriptionMode.CLUSTERING == mode) { - persistentMqConsumer.unsubscribe(topic); - } else if (SubscriptionMode.BROADCASTING == mode) { - broadcastMqConsumer.unsubscribe(topic); - } else { - throw new Exception("Unsubscribe Failed. Incorrect Subscription Mode"); + switch (mode) { + case CLUSTERING: + persistentMqConsumer.unsubscribe(topic); + break; + case BROADCASTING: + broadcastMqConsumer.unsubscribe(topic); + break; + default: + throw new Exception("Unsubscribe Failed. Incorrect Subscription Mode"); } } public void updateOffset(final SubscriptionMode subscriptionMode, final List events, final AbstractContext context) throws Exception { - if (SubscriptionMode.CLUSTERING == subscriptionMode) { - persistentMqConsumer.updateOffset(events, context); - } else if (SubscriptionMode.BROADCASTING == subscriptionMode) { - broadcastMqConsumer.updateOffset(events, context); - } else { - throw new Exception("Subscribe Failed. Incorrect Subscription Mode"); + switch (subscriptionMode) { + case CLUSTERING: + persistentMqConsumer.updateOffset(events, context); + break; + case BROADCASTING: + broadcastMqConsumer.updateOffset(events, context); + break; + default: + throw new Exception("Subscribe Failed. Incorrect Subscription Mode"); } } @@ -244,18 +306,15 @@ private EventListener createEventListener(final SubscriptionMode subscriptionMod final String topic = event.getSubject(); final String bizSeqNo = Optional.ofNullable( - (String) event.getExtension(Constants.PROPERTY_MESSAGE_SEARCH_KEYS)) - .orElseGet(() -> ""); + (String) event.getExtension(Constants.PROPERTY_MESSAGE_SEARCH_KEYS)) + .orElse(""); final String uniqueId = Optional.ofNullable((String) event.getExtension(Constants.RMB_UNIQ_ID)) - .orElseGet(() -> ""); + .orElse(""); if (log.isDebugEnabled()) { log.debug("message|mq2eventMesh|topic={}|msg={}", topic, event); } else { - if (log.isInfoEnabled()) { - log.info("message|mq2eventMesh|topic={}|bizSeqNo={}|uniqueId={}", topic, - bizSeqNo, uniqueId); - } + log.info("message|mq2eventMesh|topic={}|bizSeqNo={}|uniqueId={}", topic, bizSeqNo, uniqueId); eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromQueue(); } @@ -284,9 +343,7 @@ private EventListener createEventListener(final SubscriptionMode subscriptionMod } } } else { - if (log.isDebugEnabled()) { - log.debug("no active consumer for topic={}|msg={}", topic, event); - } + log.debug("no active consumer for topic={}|msg={}", topic, event); } eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); @@ -295,14 +352,10 @@ private EventListener createEventListener(final SubscriptionMode subscriptionMod public void sendMessageBack(final String consumerGroup, final CloudEvent event, final String uniqueId, final String bizSeqNo) throws Exception { - final EventMeshProducer producer - = eventMeshGrpcServer.getProducerManager().getEventMeshProducer(consumerGroup); + final EventMeshProducer producer = eventMeshGrpcServer.getProducerManager().getEventMeshProducer(consumerGroup); if (producer == null) { - if (log.isWarnEnabled()) { - log.warn("consumer:{} consume fail, sendMessageBack, bizSeqNo:{}, uniqueId:{}", - consumerGroup, bizSeqNo, uniqueId); - } + log.warn("consumer:{} consume fail, sendMessageBack, bizSeqNo:{}, uniqueId:{}", consumerGroup, bizSeqNo, uniqueId); return; } @@ -310,16 +363,14 @@ public void sendMessageBack(final String consumerGroup, final CloudEvent event, producer, eventMeshGrpcServer); producer.send(sendMessageBackContext, new SendCallback() { + @Override public void onSuccess(final SendResult sendResult) { } @Override public void onException(final OnExceptionContext context) { - if (log.isWarnEnabled()) { - log.warn("consumer:{} consume fail, sendMessageBack, bizSeqNo:{}, uniqueId:{}", consumerGroup, - bizSeqNo, uniqueId); - } + log.warn("consumer:{} consume fail, sendMessageBack, bizSeqNo:{}, uniqueId:{}", consumerGroup, bizSeqNo, uniqueId); } }); } 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 index 142f83faf2..6d185803e0 100644 --- 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 @@ -17,8 +17,9 @@ 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.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; import java.util.Date; @@ -42,7 +43,7 @@ public class ConsumerGroupClient { public String url; - private EventEmitter eventEmitter; + private EventEmitter eventEmitter; private final SubscriptionMode subscriptionMode; @@ -62,7 +63,7 @@ public void setUrl(String url) { this.url = url; } - public void setEventEmitter(EventEmitter emitter) { + public void setEventEmitter(EventEmitter emitter) { this.eventEmitter = emitter; } @@ -86,4 +87,3 @@ public String toString() { + ",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 index 3187c5839b..a166dab290 100644 --- 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 @@ -17,7 +17,8 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup; -import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; public abstract class ConsumerGroupTopicConfig { 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 index cda1c00537..a01058dcf5 100644 --- 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 @@ -17,9 +17,9 @@ 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.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; import org.apache.commons.collections4.MapUtils; @@ -40,33 +40,34 @@ public class StreamTopicConfig extends ConsumerGroupTopicConfig { /** * Key: IDC Value: list of emitters with Client_IP:port */ - private final transient Map>> idcEmitterMap = new ConcurrentHashMap<>(); + private final Map>> idcEmitterMap = new ConcurrentHashMap<>(); /** * Key: IDC Value: list of emitters */ - private transient Map>> idcEmitters = new ConcurrentHashMap<>(); + private Map>> idcEmitters = new ConcurrentHashMap<>(); - private transient List> totalEmitters = new ArrayList<>(); + private List> totalEmitters = new ArrayList<>(); public StreamTopicConfig(final String consumerGroup, final String topic, final SubscriptionMode subscriptionMode) { super(consumerGroup, topic, subscriptionMode, GrpcType.STREAM); } + private String concatKey(String ip, String pid) { + return ip.concat(":").concat(pid); + } + @Override public synchronized void registerClient(final ConsumerGroupClient client) { Objects.requireNonNull(client, "ConsumerGroupClient can not be null"); if (client.getGrpcType() != grpcType) { - if (log.isWarnEnabled()) { - log.warn("Invalid grpc type: {}, expecting grpc type: {}, can not register client {}", - client.getGrpcType(), grpcType, client); - } + log.warn("Invalid grpc type: {}, expecting grpc type: {}, can not register client {}", client.getGrpcType(), grpcType, client); return; } idcEmitterMap.computeIfAbsent(client.getIdc(), k -> new HashMap<>()) - .put(client.getIp() + ":" + client.getPid(), client.getEventEmitter()); + .put(concatKey(client.getIp(), client.getPid()), client.getEventEmitter()); idcEmitters = buildIdcEmitter(idcEmitterMap); totalEmitters = buildTotalEmitter(idcEmitters); @@ -78,7 +79,7 @@ public void deregisterClient(final ConsumerGroupClient client) { final String clientIp = client.getIp(); final String clientPid = client.getPid(); - final Map> emitters = idcEmitterMap.get(idc); + final Map> emitters = idcEmitterMap.get(idc); if (MapUtils.isEmpty(emitters)) { return; } @@ -104,26 +105,28 @@ public String toString() { + ",topic=" + topic + "}"; } - public Map>> getIdcEmitters() { + public Map>> getIdcEmitterMap() { + return idcEmitterMap; + } + + public Map>> getIdcEmitters() { return idcEmitters; } - public List> getTotalEmitters() { + public List> getTotalEmitters() { return totalEmitters; } - private static Map>> buildIdcEmitter( - final Map>> idcEmitterMap) { - final Map>> result = new HashMap<>(); - idcEmitterMap.forEach((k, v) -> { - result.put(k, new LinkedList>(v.values())); - }); + private static Map>> buildIdcEmitter( + final Map>> idcEmitterMap) { + final Map>> result = new HashMap<>(); + idcEmitterMap.forEach((k, v) -> result.put(k, new LinkedList<>(v.values()))); return result; } - private static List> buildTotalEmitter( - final Map>> idcEmitters) { - final List> emitterList = new LinkedList<>(); + private static List> buildTotalEmitter( + final Map>> idcEmitters) { + final List> emitterList = new LinkedList<>(); idcEmitters.values().forEach(emitterList::addAll); return emitterList; } 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 index 11fe74bd63..818efd8dc6 100644 --- 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 @@ -17,7 +17,8 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.consumer.consumergroup; -import org.apache.eventmesh.common.protocol.grpc.protos.Subscription.SubscriptionItem.SubscriptionMode; +import org.apache.eventmesh.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; import java.util.ArrayList; import java.util.HashSet; @@ -27,7 +28,6 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; - import lombok.extern.slf4j.Slf4j; @Slf4j diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/AbstractPublishBatchCloudEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/AbstractPublishBatchCloudEventProcessor.java new file mode 100644 index 0000000000..43cdb9a3cf --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/AbstractPublishBatchCloudEventProcessor.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.runtime.core.protocol.grpc.processor; + +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +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.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; + +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractPublishBatchCloudEventProcessor implements PublishProcessor { + + private static final Logger aclLogger = LoggerFactory.getLogger("acl"); + + protected final EventMeshGrpcServer eventMeshGrpcServer; + + protected final Acl acl; + + public AbstractPublishBatchCloudEventProcessor(final EventMeshGrpcServer eventMeshGrpcServer, final Acl acl) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + this.acl = acl; + } + + @Override + public void process(CloudEventBatch cloudEvent, EventEmitter emitter) throws Exception { + + // control flow rate limit + if (!eventMeshGrpcServer.getMsgRateLimiter().tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + log.error("Send message speed over limit."); + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_SEND_MESSAGE_SPEED_OVER_LIMIT_ERR, emitter); + return; + } + + StatusCode cloudEventCheck = cloudEventBatchCheck(cloudEvent); + if (cloudEventCheck != StatusCode.SUCCESS) { + ServiceUtils.sendResponseCompleted(cloudEventCheck, emitter); + return; + } + StatusCode aclCheck = this.aclCheck(cloudEvent.getEvents(0)); + if (aclCheck != StatusCode.SUCCESS) { + ServiceUtils.sendResponseCompleted(aclCheck, emitter); + return; + } + handleCloudEvent(cloudEvent, emitter); + } + + public StatusCode cloudEventBatchCheck(CloudEventBatch cloudEventBatch) { + if (!ServiceUtils.validateCloudEventBatchAttributes(cloudEventBatch)) { + return StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR; + } + + if (!ServiceUtils.validateCloudEventBatchData(cloudEventBatch)) { + return StatusCode.EVENTMESH_PROTOCOL_BODY_ERR; + } + return StatusCode.SUCCESS; + } + + public StatusCode aclCheck(CloudEvent cloudEvent) { + try { + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().isEventMeshServerSecurityEnable()) { + String remoteAdd = EventMeshCloudEventUtils.getIp(cloudEvent); + String user = EventMeshCloudEventUtils.getUserName(cloudEvent); + String pass = EventMeshCloudEventUtils.getPassword(cloudEvent); + String subsystem = EventMeshCloudEventUtils.getSys(cloudEvent); + String topic = EventMeshCloudEventUtils.getSubject(cloudEvent); + this.acl.doAclCheckInHttpSend(remoteAdd, user, pass, subsystem, topic, RequestCode.MSG_SEND_ASYNC.getRequestCode()); + } + } catch (AclException e) { + aclLogger.warn("Client has no permission,AbstructPublishCloudEventProcessor send failed", e); + return StatusCode.EVENTMESH_ACL_ERR; + } + return StatusCode.SUCCESS; + } + + abstract void handleCloudEvent(CloudEventBatch cloudEventBatch, EventEmitter emitter) throws Exception; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/AbstractPublishCloudEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/AbstractPublishCloudEventProcessor.java new file mode 100644 index 0000000000..2f46f2f067 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/AbstractPublishCloudEventProcessor.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +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.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; + +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class AbstractPublishCloudEventProcessor implements PublishProcessor { + + private static final Logger aclLogger = LoggerFactory.getLogger("acl"); + + protected final EventMeshGrpcServer eventMeshGrpcServer; + + protected final Acl acl; + + public AbstractPublishCloudEventProcessor(final EventMeshGrpcServer eventMeshGrpcServer, final Acl acl) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + this.acl = acl; + } + + @Override + public void process(CloudEvent cloudEvent, EventEmitter emitter) throws Exception { + + // control flow rate limit + if (!eventMeshGrpcServer.getMsgRateLimiter().tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { + log.error("Send message speed over limit."); + ServiceUtils.sendStreamResponseCompleted(cloudEvent, StatusCode.EVENTMESH_SEND_MESSAGE_SPEED_OVER_LIMIT_ERR, emitter); + return; + } + + StatusCode cloudEventCheck = cloudEventCheck(cloudEvent); + if (cloudEventCheck != StatusCode.SUCCESS) { + ServiceUtils.sendResponseCompleted(cloudEventCheck, emitter); + return; + } + StatusCode aclCheck = this.aclCheck(cloudEvent); + if (aclCheck != StatusCode.SUCCESS) { + ServiceUtils.sendResponseCompleted(aclCheck, emitter); + return; + } + handleCloudEvent(cloudEvent, emitter); + } + + public StatusCode cloudEventCheck(CloudEvent cloudEvent) { + if (!ServiceUtils.validateCloudEventAttributes(cloudEvent)) { + return StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR; + } + + if (!ServiceUtils.validateCloudEventData(cloudEvent)) { + return StatusCode.EVENTMESH_PROTOCOL_BODY_ERR; + } + return StatusCode.SUCCESS; + } + + public StatusCode aclCheck(CloudEvent cloudEvent) { + try { + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().isEventMeshServerSecurityEnable()) { + String remoteAdd = EventMeshCloudEventUtils.getIp(cloudEvent); + String user = EventMeshCloudEventUtils.getUserName(cloudEvent); + String pass = EventMeshCloudEventUtils.getPassword(cloudEvent); + String subsystem = EventMeshCloudEventUtils.getSys(cloudEvent); + String topic = EventMeshCloudEventUtils.getSubject(cloudEvent); + this.acl.doAclCheckInHttpSend(remoteAdd, user, pass, subsystem, topic, RequestCode.MSG_SEND_ASYNC.getRequestCode()); + } + } catch (AclException e) { + aclLogger.warn("Client has no permission,AbstructPublishCloudEventProcessor send failed", e); + return StatusCode.EVENTMESH_ACL_ERR; + } + return StatusCode.SUCCESS; + } + + abstract void handleCloudEvent(CloudEvent cloudEvent, EventEmitter emitter) throws Exception; +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/BatchPublishCloudEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/BatchPublishCloudEventProcessor.java new file mode 100644 index 0000000000..d912d82ace --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/BatchPublishCloudEventProcessor.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.core.protocol.grpc.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.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.common.BatchEventMeshCloudEventWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +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.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; +import org.apache.eventmesh.runtime.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; + +import java.util.List; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class BatchPublishCloudEventProcessor extends AbstractPublishBatchCloudEventProcessor { + + public BatchPublishCloudEventProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { + super(eventMeshGrpcServer, eventMeshGrpcServer.getAcl()); + } + + public void handleCloudEvent(CloudEventBatch cloudEventBatch, EventEmitter emitter) throws Exception { + + CloudEvent cloudEvent = cloudEventBatch.getEvents(0); + String topic = EventMeshCloudEventUtils.getSubject(cloudEvent); + String producerGroup = EventMeshCloudEventUtils.getProducerGroup(cloudEvent); + + String protocolType = EventMeshCloudEventUtils.getProtocolType(cloudEvent); + ProtocolAdaptor grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + List cloudEvents = grpcCommandProtocolAdaptor.toBatchCloudEvent( + new BatchEventMeshCloudEventWrapper(cloudEventBatch)); + + for (io.cloudevents.CloudEvent event : cloudEvents) { + String seqNum = event.getId(); + String uniqueId = (event.getExtension(ProtocolKey.UNIQUE_ID) == null) ? "" : event.getExtension(ProtocolKey.UNIQUE_ID).toString(); + ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); + EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); + + SendMessageContext sendMessageContext = new SendMessageContext(seqNum, event, eventMeshProducer, eventMeshGrpcServer); + + eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToQueue(); + long startTime = System.currentTimeMillis(); + eventMeshProducer.send(sendMessageContext, new SendCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + long endTime = System.currentTimeMillis(); + log.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(); + log.error("message|eventMesh2mq|REQ|BatchSend|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId, context.getException()); + } + }); + } + ServiceUtils.sendResponseCompleted(StatusCode.SUCCESS, "batch publish success", emitter); + } + +} 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 deleted file mode 100644 index 45f2d78035..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/BatchPublishMessageProcessor.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.Objects; -import java.util.concurrent.TimeUnit; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.cloudevents.CloudEvent; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class BatchPublishMessageProcessor { - - private final Logger aclLogger = LoggerFactory.getLogger(EventMeshConstants.ACL); - - private final EventMeshGrpcServer eventMeshGrpcServer; - - private final Acl acl; - - public BatchPublishMessageProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { - this.eventMeshGrpcServer = eventMeshGrpcServer; - this.acl = eventMeshGrpcServer.getAcl(); - } - - 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)) { - log.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) == null) - ? "" : Objects.requireNonNull(event).getExtension(ProtocolKey.UNIQUE_ID).toString(); - ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); - EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); - - SendMessageContext sendMessageContext = new SendMessageContext(seqNum, event, eventMeshProducer, eventMeshGrpcServer); - - eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToQueue(); - long startTime = System.currentTimeMillis(); - eventMeshProducer.send(sendMessageContext, new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - long endTime = System.currentTimeMillis(); - log.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(); - log.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().isEventMeshServerSecurityEnable()) { - String remoteAdd = requestHeader.getIp(); - String user = requestHeader.getUsername(); - String pass = requestHeader.getPassword(); - String subsystem = requestHeader.getSys(); - String topic = message.getTopic(); - this.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 index 63b5b7481c..a08601dc0c 100644 --- 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 @@ -18,12 +18,12 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.processor; import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.common.protocol.HeartbeatItem; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; 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.common.utils.JsonUtils; import org.apache.eventmesh.runtime.acl.Acl; import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; import org.apache.eventmesh.runtime.constants.EventMeshConstants; @@ -33,13 +33,17 @@ import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; import java.util.Date; +import java.util.List; +import java.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.core.type.TypeReference; + public class HeartbeatProcessor { - private final Logger aclLogger = LoggerFactory.getLogger(EventMeshConstants.ACL); + private static final Logger ACL_LOGGER = LoggerFactory.getLogger(EventMeshConstants.ACL); private final EventMeshGrpcServer eventMeshGrpcServer; @@ -50,46 +54,53 @@ public HeartbeatProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { this.acl = eventMeshGrpcServer.getAcl(); } - public void process(Heartbeat heartbeat, EventEmitter emitter) throws Exception { - RequestHeader header = heartbeat.getHeader(); + public void process(CloudEvent heartbeat, EventEmitter emitter) throws Exception { - if (!ServiceUtils.validateHeader(header)) { - ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + if (!ServiceUtils.validateCloudEventAttributes(heartbeat)) { + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); return; } if (!ServiceUtils.validateHeartBeat(heartbeat)) { - ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + ServiceUtils.sendResponseCompleted(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); + ACL_LOGGER.warn("CLIENT HAS NO PERMISSION, HeartbeatProcessor failed", e); + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); return; } // only handle heartbeat for consumers - ClientType clientType = heartbeat.getClientType(); - if (ClientType.SUB != clientType) { - ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + org.apache.eventmesh.common.protocol.grpc.common.ClientType clientType = EventMeshCloudEventUtils.getClientType(heartbeat); + if (org.apache.eventmesh.common.protocol.grpc.common.ClientType.SUB != clientType) { + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); return; } ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); - String consumerGroup = heartbeat.getConsumerGroup(); - + String consumerGroup = EventMeshCloudEventUtils.getConsumerGroup(heartbeat); + final String env = EventMeshCloudEventUtils.getEnv(heartbeat); + final String idc = EventMeshCloudEventUtils.getIdc(heartbeat); + final String sys = EventMeshCloudEventUtils.getSys(heartbeat); + final String ip = EventMeshCloudEventUtils.getIp(heartbeat); + final String pid = EventMeshCloudEventUtils.getPid(heartbeat); // update clients' timestamp in the heartbeat items - for (Heartbeat.HeartbeatItem item : heartbeat.getHeartbeatItemsList()) { + List heartbeatItems = JsonUtils.parseTypeReferenceObject(heartbeat.getTextData(), + new TypeReference>() { + }); + Objects.requireNonNull(heartbeatItems, "heartbeatItems can't be null"); + for (HeartbeatItem item : heartbeatItems) { ConsumerGroupClient hbClient = ConsumerGroupClient.builder() - .env(header.getEnv()) - .idc(header.getIdc()) - .sys(header.getSys()) - .ip(header.getIp()) - .pid(header.getPid()) + .env(env) + .idc(idc) + .sys(sys) + .ip(ip) + .pid(pid) .consumerGroup(consumerGroup) .topic(item.getTopic()) .lastUpTime(new Date()) @@ -97,23 +108,25 @@ public void process(Heartbeat heartbeat, EventEmitter emitter) throws // consumer group client is lost, and the client needs to resubscribe. if (!consumerManager.updateClientTime(hbClient)) { - ServiceUtils.sendRespAndDone(StatusCode.CLIENT_RESUBSCRIBE, emitter); + ServiceUtils.sendResponseCompleted(StatusCode.CLIENT_RESUBSCRIBE, emitter); return; } } - - ServiceUtils.sendRespAndDone(StatusCode.SUCCESS, "heartbeat success", emitter); + ServiceUtils.sendResponseCompleted(StatusCode.SUCCESS, "heartbeat success", emitter); } - private void doAclCheck(Heartbeat heartbeat) throws AclException { - RequestHeader header = heartbeat.getHeader(); + private void doAclCheck(CloudEvent heartbeat) throws AclException { + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().isEventMeshServerSecurityEnable()) { - String remoteAdd = header.getIp(); - String user = header.getUsername(); - String pass = header.getPassword(); - String sys = header.getSys(); + String remoteAdd = EventMeshCloudEventUtils.getIp(heartbeat); + String user = EventMeshCloudEventUtils.getUserName(heartbeat); + String pass = EventMeshCloudEventUtils.getPassword(heartbeat); + String sys = EventMeshCloudEventUtils.getSys(heartbeat); int requestCode = RequestCode.HEARTBEAT.getRequestCode(); - for (Heartbeat.HeartbeatItem item : heartbeat.getHeartbeatItemsList()) { + List heartbeatItems = JsonUtils.parseTypeReferenceObject(heartbeat.getTextData(), + new TypeReference>() { + }); + for (HeartbeatItem item : heartbeatItems) { this.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/PublishCloudEventsProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/PublishCloudEventsProcessor.java new file mode 100644 index 0000000000..996118f290 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/PublishCloudEventsProcessor.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.core.protocol.grpc.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.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +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.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; +import org.apache.eventmesh.runtime.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PublishCloudEventsProcessor extends AbstractPublishCloudEventProcessor { + + public PublishCloudEventsProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { + super(eventMeshGrpcServer, eventMeshGrpcServer.getAcl()); + } + + @Override + public void handleCloudEvent(CloudEvent message, EventEmitter emitter) throws Exception { + + String protocolType = EventMeshCloudEventUtils.getProtocolType(message); + ProtocolAdaptor grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + io.cloudevents.CloudEvent cloudEvent = grpcCommandProtocolAdaptor.toCloudEvent(new EventMeshCloudEventWrapper(message)); + + String seqNum = EventMeshCloudEventUtils.getSeqNum(message); + String uniqueId = EventMeshCloudEventUtils.getUniqueId(message); + String topic = EventMeshCloudEventUtils.getSubject(message); + String producerGroup = EventMeshCloudEventUtils.getProducerGroup(message); + + ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); + EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); + + SendMessageContext sendMessageContext = new SendMessageContext(seqNum, cloudEvent, eventMeshProducer, eventMeshGrpcServer); + + eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToQueue(); + long startTime = System.currentTimeMillis(); + eventMeshProducer.send(sendMessageContext, new SendCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + ServiceUtils.sendResponseCompleted(StatusCode.SUCCESS, sendResult.toString(), emitter); + long endTime = System.currentTimeMillis(); + log.info("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId); + eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToClient(); + } + + @Override + public void onException(OnExceptionContext context) { + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR, + EventMeshUtil.stackTrace(context.getException(), 2), emitter); + long endTime = System.currentTimeMillis(); + log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId, context.getException()); + } + }); + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/PublishProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/PublishProcessor.java new file mode 100644 index 0000000000..1d5de0b9ff --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/PublishProcessor.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.grpc.processor; + +import org.apache.eventmesh.runtime.core.protocol.grpc.service.EventEmitter; + +/** + * publish processor interface + * @param + * @param + */ +public interface PublishProcessor { + + void process(Request request, EventEmitter emitter) throws Exception; + +} 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 index 88afdf7439..fe10ff5dac 100644 --- 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 @@ -22,21 +22,23 @@ 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.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventWrapper; +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.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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; import org.apache.eventmesh.runtime.util.EventMeshUtil; import java.util.concurrent.TimeUnit; @@ -44,15 +46,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.cloudevents.CloudEvent; - - import lombok.extern.slf4j.Slf4j; @Slf4j public class ReplyMessageProcessor { - private final Logger aclLogger = LoggerFactory.getLogger(EventMeshConstants.ACL); + private static final Logger ACL_LOGGER = LoggerFactory.getLogger(EventMeshConstants.ACL); private final EventMeshGrpcServer eventMeshGrpcServer; @@ -63,24 +62,23 @@ public ReplyMessageProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { this.acl = eventMeshGrpcServer.getAcl(); } - public void process(SimpleMessage message, EventEmitter emitter) throws Exception { - RequestHeader requestHeader = message.getHeader(); + public void process(CloudEvent message, EventEmitter emitter) throws Exception { - if (!ServiceUtils.validateHeader(requestHeader)) { - ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + if (!ServiceUtils.validateCloudEventAttributes(message)) { + ServiceUtils.sendStreamResponseCompleted(message, StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); return; } - if (!ServiceUtils.validateMessage(message)) { - ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + if (!ServiceUtils.validateCloudEventData(message)) { + ServiceUtils.sendStreamResponseCompleted(message, 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); + ACL_LOGGER.warn("CLIENT HAS NO PERMISSION,RequestReplyMessageProcessor reply failed", e); + ServiceUtils.sendStreamResponseCompleted(message, StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); return; } @@ -88,31 +86,33 @@ public void process(SimpleMessage message, EventEmitter emitter) if (!eventMeshGrpcServer.getMsgRateLimiter() .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { log.error("Send message speed over limit."); - ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_SEND_MESSAGE_SPEED_OVER_LIMIT_ERR, emitter); + ServiceUtils.sendStreamResponseCompleted(message, StatusCode.EVENTMESH_SEND_MESSAGE_SPEED_OVER_LIMIT_ERR, emitter); return; } - String seqNum = message.getSeqNum(); - String uniqueId = message.getUniqueId(); - String producerGroup = message.getProducerGroup(); + String seqNum = EventMeshCloudEventUtils.getSeqNum(message); + String uniqueId = EventMeshCloudEventUtils.getUniqueId(message); + String producerGroup = EventMeshCloudEventUtils.getProducerGroup(message); - // set reply topic for ths message - String mqCluster = message.getPropertiesOrDefault(EventMeshConstants.PROPERTY_MESSAGE_CLUSTER, "defaultCluster"); + // set reply topic for this message + String mqCluster = EventMeshCloudEventUtils.getCluster(message, "defaultCluster"); String replyTopic = mqCluster + "-" + EventMeshConstants.RR_REPLY_TOPIC; - message = SimpleMessage.newBuilder(message).setTopic(replyTopic).build(); + final CloudEvent messageReply = CloudEvent.newBuilder(message) + .putAttributes(ProtocolKey.SUBJECT, CloudEventAttributeValue.newBuilder().setCeString(replyTopic).build()).build(); - String protocolType = requestHeader.getProtocolType(); + String protocolType = EventMeshCloudEventUtils.getProtocolType(messageReply); ProtocolAdaptor grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); - CloudEvent cloudEvent = grpcCommandProtocolAdaptor.toCloudEvent(new SimpleMessageWrapper(message)); + io.cloudevents.CloudEvent cloudEvent = grpcCommandProtocolAdaptor.toCloudEvent(new EventMeshCloudEventWrapper(messageReply)); ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); - SendMessageContext sendMessageContext = new SendMessageContext(message.getSeqNum(), cloudEvent, eventMeshProducer, eventMeshGrpcServer); + SendMessageContext sendMessageContext = new SendMessageContext(seqNum, cloudEvent, eventMeshProducer, eventMeshGrpcServer); eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToQueue(); long startTime = System.currentTimeMillis(); eventMeshProducer.reply(sendMessageContext, new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { long endTime = System.currentTimeMillis(); @@ -122,7 +122,7 @@ public void onSuccess(SendResult sendResult) { @Override public void onException(OnExceptionContext onExceptionContext) { - ServiceUtils.sendStreamRespAndDone(requestHeader, StatusCode.EVENTMESH_REPLY_MSG_ERR, + ServiceUtils.sendStreamResponseCompleted(messageReply, StatusCode.EVENTMESH_REPLY_MSG_ERR, EventMeshUtil.stackTrace(onExceptionContext.getException(), 2), emitter); long endTime = System.currentTimeMillis(); log.error("message|mq2eventmesh|REPLY|ReplyToServer|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", @@ -131,14 +131,14 @@ public void onException(OnExceptionContext onExceptionContext) { }); } - private void doAclCheck(SimpleMessage message) throws AclException { - RequestHeader requestHeader = message.getHeader(); + private void doAclCheck(CloudEvent message) throws AclException { + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().isEventMeshServerSecurityEnable()) { - String remoteAdd = requestHeader.getIp(); - String user = requestHeader.getUsername(); - String pass = requestHeader.getPassword(); - String subsystem = requestHeader.getSys(); - String topic = message.getTopic(); + String remoteAdd = EventMeshCloudEventUtils.getIp(message); + String user = EventMeshCloudEventUtils.getUserName(message); + String pass = EventMeshCloudEventUtils.getPassword(message); + String subsystem = EventMeshCloudEventUtils.getSys(message); + String topic = EventMeshCloudEventUtils.getSubject(message); this.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/RequestCloudEventProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/RequestCloudEventProcessor.java new file mode 100644 index 0000000000..1e934ff85c --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/RequestCloudEventProcessor.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.core.protocol.grpc.processor; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.common.protocol.ProtocolTransportObject; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventWrapper; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +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.core.protocol.grpc.service.EventEmitter; +import org.apache.eventmesh.runtime.core.protocol.grpc.service.ServiceUtils; +import org.apache.eventmesh.runtime.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.ProducerManager; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class RequestCloudEventProcessor extends AbstractPublishCloudEventProcessor { + + public RequestCloudEventProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { + super(eventMeshGrpcServer, eventMeshGrpcServer.getAcl()); + } + + @Override + public void handleCloudEvent(CloudEvent message, EventEmitter emitter) throws Exception { + + String protocolType = EventMeshCloudEventUtils.getProtocolType(message); + ProtocolAdaptor grpcCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); + io.cloudevents.CloudEvent cloudEvent = grpcCommandProtocolAdaptor.toCloudEvent(new EventMeshCloudEventWrapper(message)); + + String seqNum = EventMeshCloudEventUtils.getSeqNum(message); + String uniqueId = EventMeshCloudEventUtils.getUniqueId(message); + String topic = EventMeshCloudEventUtils.getSubject(message); + String producerGroup = EventMeshCloudEventUtils.getProducerGroup(message); + int ttl = Integer.parseInt(EventMeshCloudEventUtils.getTtl(message)); + + ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); + EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); + + SendMessageContext sendMessageContext = new SendMessageContext(seqNum, cloudEvent, eventMeshProducer, eventMeshGrpcServer); + + eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToQueue(); + long startTime = System.currentTimeMillis(); + eventMeshProducer.request(sendMessageContext, new RequestReplyCallback() { + + @Override + public void onSuccess(io.cloudevents.CloudEvent event) { + try { + eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromQueue(); + EventMeshCloudEventWrapper wrapper = (EventMeshCloudEventWrapper) grpcCommandProtocolAdaptor.fromCloudEvent(event); + + emitter.onNext(wrapper.getMessage()); + emitter.onCompleted(); + + long endTime = System.currentTimeMillis(); + log.info("message|eventmesh2client|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId); + eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToClient(); + } catch (Exception e) { + ServiceUtils.sendStreamResponseCompleted(message, StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR, EventMeshUtil.stackTrace(e, 2), + emitter); + long endTime = System.currentTimeMillis(); + log.error("message|mq2eventmesh|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId, e); + } + } + + @Override + public void onException(Throwable e) { + ServiceUtils.sendStreamResponseCompleted(message, StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR, EventMeshUtil.stackTrace(e, 2), + emitter); + long endTime = System.currentTimeMillis(); + log.error("message|eventMesh2mq|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, seqNum, uniqueId, e); + } + }, ttl); + } +} 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 deleted file mode 100644 index 6bac1eddf6..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/RequestMessageProcessor.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class RequestMessageProcessor { - - private final Logger aclLogger = LoggerFactory.getLogger(EventMeshConstants.ACL); - - private final EventMeshGrpcServer eventMeshGrpcServer; - - private final Acl acl; - - public RequestMessageProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { - this.eventMeshGrpcServer = eventMeshGrpcServer; - this.acl = eventMeshGrpcServer.getAcl(); - } - - 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; - } - - 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)) { - log.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)); - - String seqNum = message.getSeqNum(); - String uniqueId = message.getUniqueId(); - String topic = message.getTopic(); - String producerGroup = message.getProducerGroup(); - int ttl = Integer.parseInt(message.getTtl()); - - ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); - EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); - - SendMessageContext sendMessageContext = new SendMessageContext(message.getSeqNum(), cloudEvent, eventMeshProducer, eventMeshGrpcServer); - - eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToQueue(); - long startTime = System.currentTimeMillis(); - eventMeshProducer.request(sendMessageContext, new RequestReplyCallback() { - @Override - public void onSuccess(CloudEvent event) { - try { - eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromQueue(); - SimpleMessageWrapper wrapper = (SimpleMessageWrapper) grpcCommandProtocolAdaptor.fromCloudEvent(event); - - emitter.onNext(wrapper.getMessage()); - emitter.onCompleted(); - - long endTime = System.currentTimeMillis(); - log.info("message|eventmesh2client|REPLY|RequestReply|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", - endTime - startTime, topic, seqNum, uniqueId); - eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToClient(); - } catch (Exception e) { - ServiceUtils.sendStreamRespAndDone(message.getHeader(), StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR, - EventMeshUtil.stackTrace(e, 2), emitter); - - long endTime = System.currentTimeMillis(); - log.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(); - log.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().isEventMeshServerSecurityEnable()) { - String remoteAdd = requestHeader.getIp(); - String user = requestHeader.getUsername(); - String pass = requestHeader.getPassword(); - String subsystem = requestHeader.getSys(); - String topic = message.getTopic(); - this.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 deleted file mode 100644 index 4fa82ca0d9..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/processor/SendAsyncMessageProcessor.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class SendAsyncMessageProcessor { - - private final Logger aclLogger = LoggerFactory.getLogger(EventMeshConstants.ACL); - - private final EventMeshGrpcServer eventMeshGrpcServer; - - private final Acl acl; - - public SendAsyncMessageProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { - this.eventMeshGrpcServer = eventMeshGrpcServer; - this.acl = eventMeshGrpcServer.getAcl(); - } - - 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; - } - - 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)) { - log.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)); - - String seqNum = message.getSeqNum(); - String uniqueId = message.getUniqueId(); - String topic = message.getTopic(); - String producerGroup = message.getProducerGroup(); - - ProducerManager producerManager = eventMeshGrpcServer.getProducerManager(); - EventMeshProducer eventMeshProducer = producerManager.getEventMeshProducer(producerGroup); - - SendMessageContext sendMessageContext = new SendMessageContext(message.getSeqNum(), cloudEvent, - eventMeshProducer, eventMeshGrpcServer); - - eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToQueue(); - 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(); - log.info("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", - endTime - startTime, topic, seqNum, uniqueId); - eventMeshGrpcServer.getMetricsMonitor().recordSendMsgToClient(); - } - - @Override - public void onException(OnExceptionContext context) { - ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR, - EventMeshUtil.stackTrace(context.getException(), 2), emitter); - long endTime = System.currentTimeMillis(); - log.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().isEventMeshServerSecurityEnable()) { - String remoteAdd = requestHeader.getIp(); - String user = requestHeader.getUsername(); - String pass = requestHeader.getPassword(); - String subsystem = requestHeader.getSys(); - String topic = message.getTopic(); - this.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 index b48a5c992b..613e4b847a 100644 --- 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 @@ -17,19 +17,19 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.processor; - import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; 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.common.utils.JsonUtils; 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; @@ -38,14 +38,16 @@ import java.util.List; import java.util.Objects; +import com.fasterxml.jackson.core.type.TypeReference; + import lombok.extern.slf4j.Slf4j; @Slf4j public class SubscribeProcessor { - private final transient EventMeshGrpcServer eventMeshGrpcServer; + private static final GrpcType grpcType = GrpcType.WEBHOOK; - private final transient GrpcType grpcType = GrpcType.WEBHOOK; + private final EventMeshGrpcServer eventMeshGrpcServer; private final Acl acl; @@ -54,49 +56,55 @@ public SubscribeProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { this.acl = eventMeshGrpcServer.getAcl(); } - public void process(final Subscription subscription, final EventEmitter emitter) throws Exception { + public void process(final CloudEvent subscription, final EventEmitter emitter) throws Exception { Objects.requireNonNull(subscription, "subscription can not be null"); Objects.requireNonNull(emitter, "emitter can not be null"); - final RequestHeader header = subscription.getHeader(); - - if (!ServiceUtils.validateHeader(header)) { - ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + if (!ServiceUtils.validateCloudEventAttributes(subscription)) { + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); return; } if (!ServiceUtils.validateSubscription(grpcType, subscription)) { - ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); return; } - try { doAclCheck(subscription); } catch (AclException e) { - if (log.isWarnEnabled()) { - log.warn("CLIENT HAS NO PERMISSION to Subscribe. failed", e); - } - ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); + log.warn("CLIENT HAS NO PERMISSION to Subscribe. failed", e); + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); return; } final ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); - final String consumerGroup = subscription.getConsumerGroup(); + final String consumerGroup = EventMeshCloudEventUtils.getConsumerGroup(subscription); // Collect new clients in the subscription + List subscriptionItems = JsonUtils.parseTypeReferenceObject(subscription.getTextData(), + new TypeReference>() { + }); + + Objects.requireNonNull(subscriptionItems, "subscriptionItems must not be null"); + final String env = EventMeshCloudEventUtils.getEnv(subscription); + final String idc = EventMeshCloudEventUtils.getIdc(subscription); + final String sys = EventMeshCloudEventUtils.getSys(subscription); + final String ip = EventMeshCloudEventUtils.getIp(subscription); + final String pid = EventMeshCloudEventUtils.getPid(subscription); + final String url = EventMeshCloudEventUtils.getURL(subscription); final List newClients = new LinkedList<>(); - for (final Subscription.SubscriptionItem item : subscription.getSubscriptionItemsList()) { + for (final SubscriptionItem item : subscriptionItems) { final ConsumerGroupClient newClient = ConsumerGroupClient.builder() - .env(header.getEnv()) - .idc(header.getIdc()) - .sys(header.getSys()) - .ip(header.getIp()) - .pid(header.getPid()) + .env(env) + .idc(idc) + .sys(sys) + .ip(ip) + .pid(pid) .consumerGroup(consumerGroup) .topic(item.getTopic()) .grpcType(grpcType) .subscriptionMode(item.getMode()) - .url(subscription.getUrl()) + .url(url) .lastUpTime(new Date()) .build(); newClients.add(newClient); @@ -117,25 +125,24 @@ public void process(final Subscription subscription, final EventEmitter subscriptionItems = JsonUtils.parseTypeReferenceObject(subscription.getTextData(), + new TypeReference>() { + }); + Objects.requireNonNull(subscriptionItems, "subscriptionItems must not be null"); if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().isEventMeshServerSecurityEnable()) { - for (final Subscription.SubscriptionItem item : subscription.getSubscriptionItemsList()) { - this.acl.doAclCheckInHttpReceive(header.getIp(), header.getUsername(), header.getPassword(), - header.getSys(), item.getTopic(), RequestCode.SUBSCRIBE.getRequestCode()); + for (final SubscriptionItem item : subscriptionItems) { + this.acl.doAclCheckInHttpReceive(EventMeshCloudEventUtils.getConsumerGroup(subscription), + EventMeshCloudEventUtils.getUserName(subscription), EventMeshCloudEventUtils.getPassword(subscription), + EventMeshCloudEventUtils.getSys(subscription), item.getTopic(), RequestCode.SUBSCRIBE.getRequestCode()); } } } 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 index e1f25dbaa6..2cef63b47e 100644 --- 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 @@ -18,38 +18,42 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.processor; import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; 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.common.utils.JsonUtils; 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.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 java.util.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.core.type.TypeReference; import lombok.extern.slf4j.Slf4j; @Slf4j public class SubscribeStreamProcessor { - private final Logger aclLogger = LoggerFactory.getLogger("acl"); + private static final Logger ACL_LOGGER = LoggerFactory.getLogger(EventMeshConstants.ACL); private final EventMeshGrpcServer eventMeshGrpcServer; - private final GrpcType grpcType = GrpcType.STREAM; + private static final GrpcType grpcType = GrpcType.STREAM; private final Acl acl; @@ -59,42 +63,47 @@ public SubscribeStreamProcessor(final EventMeshGrpcServer eventMeshGrpcServer) { } - public void process(Subscription subscription, EventEmitter emitter) throws Exception { + public void process(CloudEvent subscription, EventEmitter emitter) throws Exception { - RequestHeader header = subscription.getHeader(); - - if (!ServiceUtils.validateHeader(header)) { - ServiceUtils.sendStreamRespAndDone(header, StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + if (!ServiceUtils.validateCloudEventAttributes(subscription)) { + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); return; } if (!ServiceUtils.validateSubscription(grpcType, subscription)) { - ServiceUtils.sendStreamRespAndDone(header, StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + ServiceUtils.sendResponseCompleted(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); + ACL_LOGGER.warn("CLIENT HAS NO PERMISSION to Subscribe. failed", e); + ServiceUtils.sendStreamResponseCompleted(subscription, StatusCode.EVENTMESH_ACL_ERR, e.getMessage(), emitter); return; } ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); - String consumerGroup = subscription.getConsumerGroup(); - List subscriptionItems = subscription.getSubscriptionItemsList(); + String consumerGroup = EventMeshCloudEventUtils.getConsumerGroup(subscription); // Collect new clients in subscription + final String env = EventMeshCloudEventUtils.getEnv(subscription); + final String idc = EventMeshCloudEventUtils.getIdc(subscription); + final String sys = EventMeshCloudEventUtils.getSys(subscription); + final String ip = EventMeshCloudEventUtils.getIp(subscription); + final String pid = EventMeshCloudEventUtils.getPid(subscription); List newClients = new LinkedList<>(); - for (Subscription.SubscriptionItem item : subscriptionItems) { + List subscriptionItems = JsonUtils.parseTypeReferenceObject(subscription.getTextData(), + new TypeReference>() { + }); + for (SubscriptionItem item : Objects.requireNonNull(subscriptionItems)) { ConsumerGroupClient newClient = ConsumerGroupClient.builder() - .env(header.getEnv()) - .idc(header.getIdc()) - .sys(header.getSys()) - .ip(header.getIp()) - .pid(header.getPid()) + .env(env) + .idc(idc) + .sys(sys) + .ip(ip) + .pid(pid) .consumerGroup(consumerGroup) .topic(item.getTopic()) .subscriptionMode(item.getMode()) @@ -128,17 +137,20 @@ public void process(Subscription subscription, EventEmitter emitt log.warn("EventMesh consumer [{}] didn't restart.", consumerGroup); } - ServiceUtils.sendStreamResp(header, StatusCode.SUCCESS, "subscribe success", emitter); + ServiceUtils.sendStreamResponse(subscription, StatusCode.SUCCESS, "subscribe success", emitter); } - private void doAclCheck(Subscription subscription) throws AclException { - RequestHeader header = subscription.getHeader(); + private void doAclCheck(CloudEvent subscription) throws AclException { + if (eventMeshGrpcServer.getEventMeshGrpcConfiguration().isEventMeshServerSecurityEnable()) { - String remoteAdd = header.getIp(); - String user = header.getUsername(); - String pass = header.getPassword(); - String subsystem = header.getSys(); - for (Subscription.SubscriptionItem item : subscription.getSubscriptionItemsList()) { + String remoteAdd = EventMeshCloudEventUtils.getIp(subscription); + String user = EventMeshCloudEventUtils.getUserName(subscription); + String pass = EventMeshCloudEventUtils.getPassword(subscription); + String subsystem = EventMeshCloudEventUtils.getSys(subscription); + List subscriptionItems = JsonUtils.parseTypeReferenceObject(subscription.getTextData(), + new TypeReference>() { + }); + for (SubscriptionItem item : Objects.requireNonNull(subscriptionItems)) { this.acl.doAclCheckInHttpReceive(remoteAdd, user, pass, subsystem, item.getTopic(), RequestCode.SUBSCRIBE.getRequestCode()); } } 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 index 65189c298f..708e3cfee4 100644 --- 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 @@ -17,10 +17,11 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.processor; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; 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.utils.JsonUtils; 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; @@ -32,6 +33,7 @@ import java.util.LinkedList; import java.util.List; +import com.fasterxml.jackson.core.type.TypeReference; import lombok.extern.slf4j.Slf4j; @@ -44,35 +46,39 @@ public UnsubscribeProcessor(EventMeshGrpcServer eventMeshGrpcServer) { this.eventMeshGrpcServer = eventMeshGrpcServer; } - public void process(Subscription subscription, EventEmitter emitter) throws Exception { + public void process(CloudEvent subscription, EventEmitter emitter) throws Exception { - RequestHeader header = subscription.getHeader(); - - if (!ServiceUtils.validateHeader(header)) { - ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); + if (!ServiceUtils.validateCloudEventAttributes(subscription)) { + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_PROTOCOL_HEADER_ERR, emitter); return; } if (!ServiceUtils.validateSubscription(null, subscription)) { - ServiceUtils.sendRespAndDone(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_PROTOCOL_BODY_ERR, emitter); return; } ConsumerManager consumerManager = eventMeshGrpcServer.getConsumerManager(); - String consumerGroup = subscription.getConsumerGroup(); - String url = subscription.getUrl(); - List subscriptionItems = subscription.getSubscriptionItemsList(); - + String consumerGroup = EventMeshCloudEventUtils.getConsumerGroup(subscription); + String url = EventMeshCloudEventUtils.getURL(subscription); + List subscriptionItems = JsonUtils.parseTypeReferenceObject(subscription.getTextData(), + new TypeReference>() { + }); + final String env = EventMeshCloudEventUtils.getEnv(subscription); + final String idc = EventMeshCloudEventUtils.getIdc(subscription); + final String sys = EventMeshCloudEventUtils.getSys(subscription); + final String ip = EventMeshCloudEventUtils.getIp(subscription); + final String pid = EventMeshCloudEventUtils.getPid(subscription); // Collect clients to remove in the unsubscribe List removeClients = new LinkedList<>(); - for (Subscription.SubscriptionItem item : subscriptionItems) { + for (SubscriptionItem item : subscriptionItems) { ConsumerGroupClient newClient = ConsumerGroupClient.builder() - .env(header.getEnv()) - .idc(header.getIdc()) - .sys(header.getSys()) - .ip(header.getIp()) - .pid(header.getPid()) + .env(env) + .idc(idc) + .sys(sys) + .ip(ip) + .pid(pid) .consumerGroup(consumerGroup) .topic(item.getTopic()) .subscriptionMode(item.getMode()) @@ -105,6 +111,6 @@ public void process(Subscription subscription, EventEmitter emitter) t log.warn("EventMesh consumer [{}] didn't restart.", consumerGroup); } - ServiceUtils.sendRespAndDone(StatusCode.SUCCESS, "unsubscribe success", emitter); + ServiceUtils.sendResponseCompleted(StatusCode.SUCCESS, "unsubscribe success", emitter); } } 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 deleted file mode 100644 index a5abe27d8e..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/EventMeshProducer.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 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.constants.EventMeshConstants; -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 lombok.extern.slf4j.Slf4j; - -@Slf4j -public class EventMeshProducer { - - 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(EventMeshConstants.PRODUCER_GROUP, producerGroupConfig.getGroupName()); - keyValue.put(EventMeshConstants.INSTANCE_NAME, EventMeshUtil.buildMeshClientID( - producerGroupConfig.getGroupName(), eventMeshGrpcConfiguration.getEventMeshCluster())); - - //TODO for defibus - keyValue.put(EventMeshConstants.EVENT_MESH_IDC, eventMeshGrpcConfiguration.getEventMeshIDC()); - mqProducerWrapper = new MQProducerWrapper( - eventMeshGrpcConfiguration.getEventMeshStoragePluginType()); - mqProducerWrapper.init(keyValue); - serviceState = ServiceState.INITED; - log.info("EventMeshProducer [{}] inited...........", producerGroupConfig.getGroupName()); - } - - public synchronized void start() throws Exception { - if (serviceState == null || ServiceState.RUNNING == serviceState) { - return; - } - - mqProducerWrapper.start(); - serviceState = ServiceState.RUNNING; - log.info("EventMeshProducer [{}] started..........", producerGroupConfig.getGroupName()); - } - - public synchronized void shutdown() throws Exception { - if (serviceState == null || ServiceState.INITED == serviceState) { - return; - } - - mqProducerWrapper.shutdown(); - serviceState = ServiceState.STOPPED; - log.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 deleted file mode 100644 index 7d14b615a0..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/ProducerManager.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 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 lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ProducerManager { - - private EventMeshGrpcServer eventMeshGrpcServer; - - private final ConcurrentHashMap producerTable = new ConcurrentHashMap<>(); - - public ProducerManager(EventMeshGrpcServer eventMeshGrpcServer) { - this.eventMeshGrpcServer = eventMeshGrpcServer; - } - - public void init() throws Exception { - log.info("Grpc ProducerManager inited......"); - } - - public void start() throws Exception { - log.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 != 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) { - log.error("shutdown eventMeshProducer[{}] err", eventMeshProducer, ex); - } - } - log.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 deleted file mode 100644 index dcc87248c5..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/producer/SendMessageContext.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.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 final 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_INCLUDE_MILLISECONDS)) - .append(",createTime=") - .append(DateFormatUtils.format(createTime, Constants.DATE_FORMAT_INCLUDE_MILLISECONDS)).append("}"); - return sb.toString(); - } - - @Override - public void retry() throws Exception { - if (eventMeshProducer == null) { - logger.error("Exception happends during retry. EventMeshProducer is null."); - return; - } - - if (retryTimes > 0) { //retry once - logger.error("Exception happends during retry. The retryTimes > 0."); - return; - } - - retryTimes++; - eventMeshProducer.send(this, new SendCallback() { - - @Override - public void onSuccess(SendResult sendResult) { - } - - @Override - public void onException(OnExceptionContext context) { - logger.warn("", context.getException()); - } - }); - } -} 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 index c3a0067f48..54056c3a11 100644 --- 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 @@ -20,9 +20,10 @@ 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.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventWrapper; import org.apache.eventmesh.protocol.api.ProtocolAdaptor; import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; @@ -36,10 +37,9 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import io.cloudevents.CloudEvent; - import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; @@ -58,8 +58,8 @@ public abstract class AbstractPushRequest extends RetryContext { protected Map> waitingRequests; protected HandleMsgContext handleMsgContext; - // protected CloudEvent event; - protected SimpleMessage simpleMessage; + // protected CloudEvent event; + protected CloudEvent eventMeshCloudEvent; private final AtomicBoolean complete = new AtomicBoolean(Boolean.FALSE); @@ -71,45 +71,39 @@ public AbstractPushRequest(HandleMsgContext handleMsgContext, Map protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); ProtocolTransportObject protocolTransportObject = protocolAdaptor.fromCloudEvent(cloudEvent); - return ((SimpleMessageWrapper) protocolTransportObject).getMessage(); + return ((EventMeshCloudEventWrapper) protocolTransportObject).getMessage(); } catch (Exception e) { log.error("Error in getting EventMeshMessage from CloudEvent", e); return null; } } - private CloudEvent getCloudEvent(SimpleMessage simpleMessage) { + private io.cloudevents.CloudEvent getCloudEvent(CloudEvent cloudEvent) { try { - String protocolType = Objects.requireNonNull(simpleMessage.getHeader().getProtocolType()); + String protocolType = Objects.requireNonNull(EventMeshCloudEventUtils.getProtocolType(cloudEvent)); ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); - return protocolAdaptor.toCloudEvent(new SimpleMessageWrapper(simpleMessage)); + return protocolAdaptor.toCloudEvent(new EventMeshCloudEventWrapper(cloudEvent)); } catch (Exception e) { log.error("Error in getting CloudEvent from EventMeshMessage", e); return null; } } - @Override - public void retry() { - tryPushRequest(); - } - 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); + grpcRetryer.newTimeout(this, EventMeshConstants.DEFAULT_PUSH_RETRY_TIME_DISTANCE_IN_MILLSECONDS, TimeUnit.MILLISECONDS); } else { complete(); } @@ -122,7 +116,7 @@ protected boolean isComplete() { private void finish() { AbstractContext context = handleMsgContext.getContext(); SubscriptionMode subscriptionMode = handleMsgContext.getSubscriptionMode(); - CloudEvent event = getCloudEvent(simpleMessage); + io.cloudevents.CloudEvent event = getCloudEvent(eventMeshCloudEvent); if (eventMeshConsumer != null && context != null && event != null) { try { eventMeshConsumer.updateOffset(subscriptionMode, Collections.singletonList(event), context); @@ -138,7 +132,7 @@ protected void complete() { } protected void timeout() { - if (!isComplete() && System.currentTimeMillis() - lastPushTime >= Long.parseLong(simpleMessage.getTtl())) { + if (!isComplete() && System.currentTimeMillis() - lastPushTime >= Long.parseLong(EventMeshCloudEventUtils.getTtl(eventMeshCloudEvent))) { delayRetry(); } } @@ -161,4 +155,9 @@ protected void removeWaitingMap(WebhookPushRequest request) { waitingRequests.get(handleMsgContext.getConsumerGroup()).remove(request); } } + + @Override + public void doRun() throws Exception { + tryPushRequest(); + } } 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 index 6e7e23ab11..da666d9422 100644 --- 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 @@ -18,11 +18,11 @@ 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.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; 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; @@ -91,7 +91,6 @@ public GrpcType getGrpcType() { return grpcType; } - @Override public String toString() { return "handleMsgContext={" 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 index addd6df9f0..15e3ae93df 100644 --- 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 @@ -18,7 +18,7 @@ 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.eventmesh.common.protocol.grpc.common.GrpcType; import org.apache.commons.collections4.MapUtils; @@ -29,7 +29,6 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; - import com.google.common.collect.Maps; import com.google.common.collect.Sets; 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 index 1619943fa3..e4c84bdf64 100644 --- 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 @@ -17,8 +17,10 @@ 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.common.protocol.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; 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; @@ -34,15 +36,14 @@ import io.grpc.stub.StreamObserver; - import lombok.extern.slf4j.Slf4j; @Slf4j public class StreamPushRequest extends AbstractPushRequest { - private final Map>> idcEmitters; + private final Map>> idcEmitters; - private final List> totalEmitters; + private final List> totalEmitters; private final SubscriptionMode subscriptionMode; @@ -60,65 +61,66 @@ public StreamPushRequest(HandleMsgContext handleMsgContext, Map> eventEmitters = selectEmitter(); + List> eventEmitters = selectEmitter(); - for (EventEmitter eventEmitter : eventEmitters) { + for (EventEmitter eventEmitter : eventEmitters) { this.lastPushTime = System.currentTimeMillis(); - simpleMessage = SimpleMessage.newBuilder(simpleMessage) - .putProperties(EventMeshConstants.REQ_EVENTMESH2C_TIMESTAMP, String.valueOf(lastPushTime)).build(); + eventMeshCloudEvent = CloudEvent.newBuilder(eventMeshCloudEvent) + .putAttributes(EventMeshConstants.REQ_EVENTMESH2C_TIMESTAMP, + CloudEventAttributeValue.newBuilder().setCeString(String.valueOf(lastPushTime)).build()) + .build(); try { // catch the error and retry, don't use eventEmitter.onNext() to hide the error - StreamObserver emitter = eventEmitter.getEmitter(); + StreamObserver emitter = eventEmitter.getEmitter(); synchronized (emitter) { - emitter.onNext(simpleMessage); + emitter.onNext(eventMeshCloudEvent); } long cost = System.currentTimeMillis() - lastPushTime; log.info("message|eventMesh2client|emitter|topic={}|bizSeqNo={}" + "|uniqueId={}|cost={}", - simpleMessage.getTopic(), simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), cost); + EventMeshCloudEventUtils.getSubject(eventMeshCloudEvent), EventMeshCloudEventUtils.getSeqNum(eventMeshCloudEvent), + EventMeshCloudEventUtils.getUniqueId(eventMeshCloudEvent), cost); complete(); } catch (Throwable t) { long cost = System.currentTimeMillis() - lastPushTime; log.error("message|eventMesh2client|exception={} |emitter|topic={}|bizSeqNo={}" + "|uniqueId={}|cost={}", - t.getMessage(), simpleMessage.getTopic(), simpleMessage.getSeqNum(), - simpleMessage.getUniqueId(), cost, t); + t.getMessage(), EventMeshCloudEventUtils.getSubject(eventMeshCloudEvent), EventMeshCloudEventUtils.getSeqNum(eventMeshCloudEvent), + EventMeshCloudEventUtils.getUniqueId(eventMeshCloudEvent), cost, t); delayRetry(); } } } - private List> selectEmitter() { - List> emitterList = MapUtils.getObject(idcEmitters, + private List> selectEmitter() { + List> emitterList = MapUtils.getObject(idcEmitters, eventMeshGrpcConfiguration.getEventMeshIDC(), null); if (CollectionUtils.isNotEmpty(emitterList)) { - if (subscriptionMode == SubscriptionMode.CLUSTERING) { - return Collections.singletonList(emitterList.get((startIdx + retryTimes) % emitterList.size())); - } else if (subscriptionMode == SubscriptionMode.BROADCASTING) { - return emitterList; - } else { - log.error("Invalid Subscription Mode, no message returning back to subscriber."); - return Collections.emptyList(); - } + return getEventEmitters(emitterList); } if (CollectionUtils.isNotEmpty(totalEmitters)) { - if (subscriptionMode == SubscriptionMode.CLUSTERING) { - return Collections.singletonList(totalEmitters.get((startIdx + retryTimes) % totalEmitters.size())); - } else if (subscriptionMode == SubscriptionMode.BROADCASTING) { - return totalEmitters; - } else { - log.error("Invalid Subscription Mode, no message returning back to subscriber."); - return Collections.emptyList(); - } + return getEventEmitters(totalEmitters); } log.error("No event emitters from subscriber, no message returning."); return Collections.emptyList(); } + + private List> getEventEmitters(List> emitterList) { + switch (subscriptionMode) { + case CLUSTERING: + return Collections.singletonList(emitterList.get((startIdx + retryTimes) % emitterList.size())); + case BROADCASTING: + return emitterList; + default: + log.error("Invalid Subscription Mode, no message returning back to subscriber."); + 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 index 406e1b7832..b170257c9e 100644 --- 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 @@ -18,9 +18,10 @@ 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.SubscriptionMode; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; 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; @@ -91,7 +92,7 @@ public WebhookPushRequest(HandleMsgContext handleMsgContext, @Override public void tryPushRequest() { - if (simpleMessage == null) { + if (eventMeshCloudEvent == null) { return; } @@ -112,46 +113,41 @@ public void tryPushRequest() { builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshGrpcConfiguration.getEventMeshEnv()); builder.addHeader(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshGrpcConfiguration.getEventMeshIDC()); - 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, + builder.addHeader(ProtocolKey.PROTOCOL_TYPE, EventMeshCloudEventUtils.getProtocolType(eventMeshCloudEvent)); + builder.addHeader(ProtocolKey.PROTOCOL_DESC, EventMeshCloudEventUtils.getProtocolDesc(eventMeshCloudEvent)); + builder.addHeader(ProtocolKey.PROTOCOL_VERSION, EventMeshCloudEventUtils.getProtocolVersion(eventMeshCloudEvent)); + builder.addHeader(ProtocolKey.CONTENT_TYPE, EventMeshCloudEventUtils.getContentType(eventMeshCloudEvent, Constants.CONTENT_TYPE_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.CONTENT, EventMeshCloudEventUtils.getDataContent(eventMeshCloudEvent))); + body.add(new BasicNameValuePair(PushMessageRequestBody.BIZSEQNO, EventMeshCloudEventUtils.getSeqNum(eventMeshCloudEvent))); + body.add(new BasicNameValuePair(PushMessageRequestBody.UNIQUEID, EventMeshCloudEventUtils.getUniqueId(eventMeshCloudEvent))); body.add(new BasicNameValuePair(PushMessageRequestBody.RANDOMNO, handleMsgContext.getMsgRandomNo())); - body.add(new BasicNameValuePair(PushMessageRequestBody.TOPIC, simpleMessage.getTopic())); + body.add(new BasicNameValuePair(PushMessageRequestBody.TOPIC, EventMeshCloudEventUtils.getSubject(eventMeshCloudEvent))); body.add(new BasicNameValuePair(PushMessageRequestBody.EXTFIELDS, - JsonUtils.toJSONString(simpleMessage.getPropertiesMap()))); + JsonUtils.toJSONString(EventMeshCloudEventUtils.getAttributes(eventMeshCloudEvent)))); - simpleMessage = SimpleMessage.newBuilder(simpleMessage) - .putProperties(EventMeshConstants.REQ_EVENTMESH2C_TIMESTAMP, String.valueOf(lastPushTime)) - .build(); + eventMeshCloudEvent = CloudEvent.newBuilder(eventMeshCloudEvent).putAttributes(EventMeshConstants.REQ_EVENTMESH2C_TIMESTAMP, + CloudEventAttributeValue.newBuilder().setCeString(String.valueOf(lastPushTime)).build()).build(); builder.setEntity(new UrlEncodedFormEntity(body, StandardCharsets.UTF_8)); - addToWaitingMap(this); - CMD_LOGGER.info("cmd={}|eventMesh2client|from={}|to={}", requestCode, - IPUtils.getLocalAddress(), selectedPushUrl); + CMD_LOGGER.info("cmd={}|eventMesh2client|from={}|to={}", requestCode, IPUtils.getLocalAddress(), selectedPushUrl); try { eventMeshGrpcServer.getHttpClient().execute(builder, handleResponse(selectedPushUrl)); - MESSAGE_LOGGER - .info("message|eventMesh2client|url={}|topic={}|bizSeqNo={}|uniqueId={}", - selectedPushUrl, simpleMessage.getTopic(), simpleMessage.getSeqNum(), - simpleMessage.getUniqueId()); + MESSAGE_LOGGER.info("message|eventMesh2client|url={}|topic={}|bizSeqNo={}|uniqueId={}", + selectedPushUrl, EventMeshCloudEventUtils.getSubject(eventMeshCloudEvent), + EventMeshCloudEventUtils.getSeqNum(eventMeshCloudEvent), + EventMeshCloudEventUtils.getUniqueId(eventMeshCloudEvent)); } catch (IOException e) { long cost = System.currentTimeMillis() - lastPushTime; - MESSAGE_LOGGER.error( - "message|eventMesh2client|exception={} |emitter|topic={}|bizSeqNo={}" - + "|uniqueId={}|cost={}", e.getMessage(), simpleMessage.getTopic(), - simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), cost, e); + MESSAGE_LOGGER.error("message|eventMesh2client|exception={} |emitter|topic={}|bizSeqNo={}|uniqueId={}|cost={}", + e.getMessage(), EventMeshCloudEventUtils.getSubject(eventMeshCloudEvent), + EventMeshCloudEventUtils.getSeqNum(eventMeshCloudEvent), EventMeshCloudEventUtils.getUniqueId(eventMeshCloudEvent), cost, e); removeWaitingMap(this); delayRetry(); } @@ -161,10 +157,10 @@ public void tryPushRequest() { @Override public String toString() { return "asyncPushRequest={" - + "bizSeqNo=" + simpleMessage.getSeqNum() + + "bizSeqNo=" + EventMeshCloudEventUtils.getSeqNum(eventMeshCloudEvent) + ",startIdx=" + startIdx + ",retryTimes=" + retryTimes - + ",uniqueId=" + simpleMessage.getUniqueId() + + ",uniqueId=" + EventMeshCloudEventUtils.getUniqueId(eventMeshCloudEvent) + ",executeTime=" + DateFormatUtils.format(executeTime, Constants.DATE_FORMAT_INCLUDE_MILLISECONDS) + ",lastPushTime=" @@ -177,14 +173,11 @@ private ResponseHandler handleResponse(String selectedPushUrl) { return response -> { removeWaitingMap(WebhookPushRequest.this); long cost = System.currentTimeMillis() - lastPushTime; - - if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - - MESSAGE_LOGGER.info( - "message|eventMesh2client|exception|url={}|topic={}|bizSeqNo={}" - + "|uniqueId={}|cost={}", selectedPushUrl, simpleMessage.getTopic(), - simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), cost); + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + MESSAGE_LOGGER.info("message|eventMesh2client|exception|url={}|topic={}|bizSeqNo={}|uniqueId={}|cost={}", selectedPushUrl, + EventMeshCloudEventUtils.getSubject(eventMeshCloudEvent), EventMeshCloudEventUtils.getSeqNum(eventMeshCloudEvent), + EventMeshCloudEventUtils.getUniqueId(eventMeshCloudEvent), cost); delayRetry(); } else { String res = ""; @@ -196,14 +189,20 @@ private ResponseHandler handleResponse(String selectedPushUrl) { return new Object(); } ClientRetCode result = processResponseContent(res, selectedPushUrl); - MESSAGE_LOGGER.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(); + MESSAGE_LOGGER.info("message|eventMesh2client|{}|url={}|topic={}|bizSeqNo={}|uniqueId={}|cost={}", + result, selectedPushUrl, EventMeshCloudEventUtils.getSubject(eventMeshCloudEvent), + EventMeshCloudEventUtils.getSeqNum(eventMeshCloudEvent), EventMeshCloudEventUtils.getUniqueId(eventMeshCloudEvent), cost); + switch (result) { + case OK: + case FAIL: + complete(); + break; + case RETRY: + case NOLISTEN: + delayRetry(); + break; + default: + // do nothing } } return new Object(); @@ -226,7 +225,7 @@ private ClientRetCode processResponseContent(String content, String selectedPush return ClientRetCode.FAIL; } catch (Exception e) { MESSAGE_LOGGER.warn("url:{}, bizSeqno:{}, uniqueId:{}, httpResponse:{}", selectedPushUrl, - simpleMessage.getSeqNum(), simpleMessage.getUniqueId(), content); + EventMeshCloudEventUtils.getSeqNum(eventMeshCloudEvent), EventMeshCloudEventUtils.getUniqueId(eventMeshCloudEvent), content); return ClientRetCode.FAIL; } } @@ -236,27 +235,23 @@ private List getUrl() { List localIdcUrl = MapUtils.getObject(urls, eventMeshGrpcConfiguration.getEventMeshIDC(), null); if (CollectionUtils.isNotEmpty(localIdcUrl)) { - if (subscriptionMode == SubscriptionMode.CLUSTERING) { - return Collections.singletonList(localIdcUrl.get((startIdx + retryTimes) % localIdcUrl.size())); - } else if (subscriptionMode == SubscriptionMode.BROADCASTING) { - return localIdcUrl; - } else { - MESSAGE_LOGGER.error("Invalid Subscription Mode, no message returning back to subscriber."); - return Collections.emptyList(); - } + return getStringList(localIdcUrl); + } else if (CollectionUtils.isNotEmpty(totalUrls)) { + return getStringList(totalUrls); } + MESSAGE_LOGGER.error("No event emitters from subscriber, no message returning."); + return Collections.emptyList(); + } - if (CollectionUtils.isNotEmpty(totalUrls)) { - if (subscriptionMode == SubscriptionMode.CLUSTERING) { - return Collections.singletonList(totalUrls.get((startIdx + retryTimes) % totalUrls.size())); - } else if (subscriptionMode == SubscriptionMode.BROADCASTING) { - return totalUrls; - } else { + private List getStringList(List stringList) { + switch (subscriptionMode) { + case CLUSTERING: + return Collections.singletonList(stringList.get((startIdx + retryTimes) % stringList.size())); + case BROADCASTING: + return stringList; + default: MESSAGE_LOGGER.error("Invalid Subscription Mode, no message returning back to subscriber."); return Collections.emptyList(); - } } - MESSAGE_LOGGER.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/retry/GrpcRetryer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/retry/GrpcRetryer.java index 4c5cea1036..dccd782c1f 100644 --- 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 @@ -17,20 +17,14 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.retry; -import org.apache.eventmesh.common.EventMeshThreadFactory; +import org.apache.eventmesh.retry.api.AbstractRetryer; import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; import org.apache.eventmesh.runtime.configuration.EventMeshGrpcConfiguration; -import org.apache.eventmesh.runtime.core.protocol.DelayRetryable; - -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.DelayQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; @Slf4j -public class GrpcRetryer { +public class GrpcRetryer extends AbstractRetryer { private final EventMeshGrpcConfiguration grpcConfiguration; @@ -38,65 +32,4 @@ public GrpcRetryer(EventMeshGrpcServer eventMeshGrpcServer) { this.grpcConfiguration = eventMeshGrpcServer.getEventMeshGrpcConfiguration(); } - private final DelayQueue failed = new DelayQueue(); - - private ThreadPoolExecutor pool; - - private Thread dispatcher; - - public void pushRetry(DelayRetryable delayRetryable) { - if (failed.size() >= grpcConfiguration.getEventMeshServerRetryBlockQueueSize()) { - log.error("[RETRY-QUEUE] is full!"); - return; - } - failed.offer(delayRetryable); - } - - public void init() { - pool = new ThreadPoolExecutor( - grpcConfiguration.getEventMeshServerRetryThreadNum(), - grpcConfiguration.getEventMeshServerRetryThreadNum(), 60000, TimeUnit.MILLISECONDS, - new ArrayBlockingQueue<>(grpcConfiguration.getEventMeshServerRetryBlockQueueSize()), - new EventMeshThreadFactory("grpc-retry", true, Thread.NORM_PRIORITY), - 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 (log.isDebugEnabled()) { - log.debug("retryObj : {}", delayRetryable); - } - } catch (Exception e) { - log.error("grpc-retry-dispatcher error!", e); - } - }); - } - } catch (Exception e) { - log.error("grpc-retry-dispatcher error!", e); - } - }, "grpc-retry-dispatcher"); - dispatcher.setDaemon(true); - log.info("GrpcRetryer inited......"); - } - - public int size() { - return failed.size(); - } - - public void shutdown() { - dispatcher.interrupt(); - pool.shutdown(); - log.info("GrpcRetryer shutdown......"); - } - - public void start() throws Exception { - dispatcher.start(); - log.info("GrpcRetryer started......"); - } } 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 index 2329146b80..8963cb95bc 100644 --- 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 @@ -17,11 +17,12 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.service; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.ConsumerServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +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.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; @@ -29,6 +30,9 @@ import org.apache.eventmesh.runtime.core.protocol.grpc.processor.SubscribeStreamProcessor; import org.apache.eventmesh.runtime.core.protocol.grpc.processor.UnsubscribeProcessor; +import org.apache.commons.lang3.StringUtils; + +import java.util.Optional; import java.util.concurrent.ThreadPoolExecutor; import io.grpc.stub.StreamObserver; @@ -53,13 +57,13 @@ public ConsumerService(EventMeshGrpcServer eventMeshGrpcServer, } @Override - public void subscribe(Subscription request, StreamObserver responseObserver) { + public void subscribe(CloudEvent request, StreamObserver responseObserver) { log.info("cmd={}|{}|client2eventMesh|from={}|to={}", "subscribe", EventMeshConstants.PROTOCOL_GRPC, - request.getHeader().getIp(), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); + EventMeshCloudEventUtils.getIp(request), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(); - EventEmitter emitter = new EventEmitter<>(responseObserver); + EventEmitter emitter = new EventEmitter<>(responseObserver); subscribeThreadPoolExecutor.submit(() -> { SubscribeProcessor subscribeProcessor = new SubscribeProcessor(eventMeshGrpcServer); try { @@ -67,31 +71,31 @@ public void subscribe(Subscription request, StreamObserver responseObs } catch (Exception e) { log.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); + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), emitter); } }); } @Override - public StreamObserver subscribeStream(StreamObserver responseObserver) { - EventEmitter emitter = new EventEmitter<>(responseObserver); + public StreamObserver subscribeStream(StreamObserver responseObserver) { + EventEmitter emitter = new EventEmitter<>(responseObserver); - return new StreamObserver() { - @Override - public void onNext(Subscription subscription) { - if (!subscription.getSubscriptionItemsList().isEmpty()) { - log.info("cmd={}|{}|client2eventMesh|from={}|to={}", - "subscribeStream", EventMeshConstants.PROTOCOL_GRPC, - subscription.getHeader().getIp(), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); - eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(); + return new StreamObserver() { - handleSubscriptionStream(subscription, emitter); + @Override + public void onNext(CloudEvent subscription) { + final String subMessageType = Optional.ofNullable(subscription.getAttributesMap().get(ProtocolKey.SUB_MESSAGE_TYPE)) + .orElse(CloudEventAttributeValue.newBuilder().build()).getCeString(); + if (StringUtils.equals(subMessageType, ProtocolKey.SUB_REPLY_MESSAGE)) { + log.info("cmd={}|{}|client2eventMesh|from={}|to={}", "reply-to-server", EventMeshConstants.PROTOCOL_GRPC, + EventMeshCloudEventUtils.getIp(subscription), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); + handleSubscribeReply(subscription, emitter); } else { - log.info("cmd={}|{}|client2eventMesh|from={}|to={}", - "reply-to-server", EventMeshConstants.PROTOCOL_GRPC, - subscription.getHeader().getIp(), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); + log.info("cmd={}|{}|client2eventMesh|from={}|to={}", "subscribeStream", EventMeshConstants.PROTOCOL_GRPC, + EventMeshCloudEventUtils.getIp(subscription), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); - handleSubscribeReply(subscription, emitter); + eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(); + handleSubscriptionStream(subscription, emitter); } } @@ -109,52 +113,37 @@ public void onCompleted() { }; } - private void handleSubscriptionStream(Subscription request, EventEmitter emitter) { + private void handleSubscriptionStream(CloudEvent request, EventEmitter emitter) { subscribeThreadPoolExecutor.submit(() -> { SubscribeStreamProcessor streamProcessor = new SubscribeStreamProcessor(eventMeshGrpcServer); try { streamProcessor.process(request, emitter); } catch (Exception e) { log.error("Error code {}, error message {}", StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), e); - ServiceUtils.sendStreamRespAndDone(request.getHeader(), StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), emitter); + ServiceUtils.sendStreamResponseCompleted(request, StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), emitter); } }); } - private void handleSubscribeReply(Subscription subscription, EventEmitter emitter) { + private void handleSubscribeReply(CloudEvent subscription, EventEmitter emitter) { replyThreadPoolExecutor.submit(() -> { ReplyMessageProcessor replyMessageProcessor = new ReplyMessageProcessor(eventMeshGrpcServer); try { - replyMessageProcessor.process(buildSimpleMessage(subscription), emitter); + replyMessageProcessor.process(subscription, emitter); } catch (Exception e) { log.error("Error code {}, error message {}", StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), e); - ServiceUtils.sendStreamRespAndDone(subscription.getHeader(), StatusCode.EVENTMESH_SUBSCRIBE_ERR, e.getMessage(), emitter); + ServiceUtils.sendStreamResponseCompleted(subscription, 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(); - } - @Override - public void unsubscribe(Subscription request, StreamObserver responseObserver) { - log.info("cmd={}|{}|client2eventMesh|from={}|to={}", - "unsubscribe", EventMeshConstants.PROTOCOL_GRPC, - request.getHeader().getIp(), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); + public void unsubscribe(CloudEvent request, StreamObserver responseObserver) { + log.info("cmd={}|{}|client2eventMesh|from={}|to={}", "unsubscribe", EventMeshConstants.PROTOCOL_GRPC, + EventMeshCloudEventUtils.getIp(request), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(); - EventEmitter emitter = new EventEmitter<>(responseObserver); + EventEmitter emitter = new EventEmitter<>(responseObserver); subscribeThreadPoolExecutor.submit(() -> { UnsubscribeProcessor unsubscribeProcessor = new UnsubscribeProcessor(eventMeshGrpcServer); try { @@ -162,7 +151,7 @@ public void unsubscribe(Subscription request, StreamObserver responseO } catch (Exception e) { log.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); + ServiceUtils.sendResponseCompleted(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 index c1eec14a5c..c4b21106b8 100644 --- 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 @@ -19,7 +19,6 @@ import io.grpc.stub.StreamObserver; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -34,24 +33,24 @@ public EventEmitter(StreamObserver emitter) { public synchronized void onNext(T event) { try { emitter.onNext(event); - } catch (Throwable t) { - log.warn("StreamObserver Error onNext. {}", t.getMessage()); + } catch (Exception e) { + log.warn("StreamObserver Error onNext. {}", e.getMessage()); } } public synchronized void onCompleted() { try { emitter.onCompleted(); - } catch (Throwable t) { - log.warn("StreamObserver Error onCompleted. {}", t.getMessage()); + } catch (Exception e) { + log.warn("StreamObserver Error onCompleted. {}", e.getMessage()); } } public synchronized void onError(Throwable t) { try { emitter.onError(t); - } catch (Throwable t1) { - log.warn("StreamObserver Error onError. {}", t1.getMessage()); + } catch (Exception e) { + log.warn("StreamObserver Error onError. {}", e.getMessage()); } } 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 index 0837e827ac..10dbcaf900 100644 --- 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 @@ -17,10 +17,10 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.service; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.HeartbeatServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; 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; @@ -29,7 +29,6 @@ import io.grpc.stub.StreamObserver; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -46,12 +45,12 @@ public HeartbeatService(final EventMeshGrpcServer eventMeshGrpcServer, } @Override - public void heartbeat(Heartbeat request, StreamObserver responseObserver) { + public void heartbeat(CloudEvent request, StreamObserver responseObserver) { log.info("cmd={}|{}|client2eventMesh|from={}|to={}", - "heartbeat", EventMeshConstants.PROTOCOL_GRPC, request.getHeader().getIp(), + "heartbeat", EventMeshConstants.PROTOCOL_GRPC, EventMeshCloudEventUtils.getIp(request), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); - EventEmitter emitter = new EventEmitter<>(responseObserver); + EventEmitter emitter = new EventEmitter<>(responseObserver); threadPoolExecutor.submit(() -> { HeartbeatProcessor heartbeatProcessor = new HeartbeatProcessor(eventMeshGrpcServer); try { @@ -59,7 +58,7 @@ public void heartbeat(Heartbeat request, StreamObserver responseObserv } catch (Exception e) { log.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); + ServiceUtils.sendResponseCompleted(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 deleted file mode 100644 index 080e9eeecc..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/ProducerService.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 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; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ProducerService extends PublisherServiceGrpc.PublisherServiceImplBase { - - private final Logger cmdLogger = LoggerFactory.getLogger(EventMeshConstants.CMD); - - private final EventMeshGrpcServer eventMeshGrpcServer; - - private final ThreadPoolExecutor threadPoolExecutor; - - public ProducerService(EventMeshGrpcServer eventMeshGrpcServer, - ThreadPoolExecutor threadPoolExecutor) { - this.eventMeshGrpcServer = eventMeshGrpcServer; - this.threadPoolExecutor = threadPoolExecutor; - } - - @Override - public void publish(SimpleMessage request, StreamObserver responseObserver) { - cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", "AsyncPublish", - EventMeshConstants.PROTOCOL_GRPC, request.getHeader().getIp(), - eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); - eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(); - - EventEmitter emitter = new EventEmitter<>(responseObserver); - threadPoolExecutor.submit(() -> { - SendAsyncMessageProcessor sendAsyncMessageProcessor = new SendAsyncMessageProcessor(eventMeshGrpcServer); - try { - sendAsyncMessageProcessor.process(request, emitter); - } catch (Exception e) { - log.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); - } - }); - } - - @Override - public void requestReply(SimpleMessage request, StreamObserver responseObserver) { - cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", "RequestReply", - EventMeshConstants.PROTOCOL_GRPC, request.getHeader().getIp(), - eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); - eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(); - - EventEmitter emitter = new EventEmitter<>(responseObserver); - threadPoolExecutor.submit(() -> { - RequestMessageProcessor requestMessageProcessor = new RequestMessageProcessor(eventMeshGrpcServer); - try { - requestMessageProcessor.process(request, emitter); - } catch (Exception e) { - log.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); - } - }); - } - - @Override - public void batchPublish(BatchMessage request, StreamObserver responseObserver) { - cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", "BatchPublish", - EventMeshConstants.PROTOCOL_GRPC, request.getHeader().getIp(), - eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); - eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(request.getMessageItemCount()); - - EventEmitter emitter = new EventEmitter<>(responseObserver); - threadPoolExecutor.submit(() -> { - BatchPublishMessageProcessor batchPublishMessageProcessor = new BatchPublishMessageProcessor(eventMeshGrpcServer); - try { - batchPublishMessageProcessor.process(request, emitter); - } catch (Exception e) { - log.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/PublisherService.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/PublisherService.java new file mode 100644 index 0000000000..1d67ab8669 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/grpc/service/PublisherService.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.PublisherServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.StatusCode; +import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.BatchPublishCloudEventProcessor; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.PublishCloudEventsProcessor; +import org.apache.eventmesh.runtime.core.protocol.grpc.processor.RequestCloudEventProcessor; + +import java.util.concurrent.ThreadPoolExecutor; + +import io.grpc.stub.StreamObserver; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class PublisherService extends PublisherServiceGrpc.PublisherServiceImplBase { + + private final EventMeshGrpcServer eventMeshGrpcServer; + + private final ThreadPoolExecutor threadPoolExecutor; + + public PublisherService(EventMeshGrpcServer eventMeshGrpcServer, + ThreadPoolExecutor threadPoolExecutor) { + this.eventMeshGrpcServer = eventMeshGrpcServer; + this.threadPoolExecutor = threadPoolExecutor; + } + + /** + *
+     * Sync publish event
+     * 
+ * + * @param request + * @param responseObserver + */ + @Override + public void publish(CloudEvent request, StreamObserver responseObserver) { + log.info("cmd={}|{}|client2eventMesh|from={}|to={}", "publish", EventMeshConstants.PROTOCOL_GRPC, + EventMeshCloudEventUtils.getIp(request), eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); + eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(); + + EventEmitter emitter = new EventEmitter<>(responseObserver); + threadPoolExecutor.submit(() -> { + PublishCloudEventsProcessor publishCloudEventsProcessor = new PublishCloudEventsProcessor(eventMeshGrpcServer); + try { + publishCloudEventsProcessor.process(request, emitter); + } catch (Exception e) { + log.error("Error code {}, error message {}", StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode(), + StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg(), e); + ServiceUtils.sendResponseCompleted(StatusCode.EVENTMESH_SEND_ASYNC_MSG_ERR, e.getMessage(), emitter); + } + }); + } + + /** + *
+     * publish event with reply
+     * 
+ * + * @param request + * @param responseObserver + */ + @Override + public void requestReply(CloudEvent request, StreamObserver responseObserver) { + log.info("cmd={}|{}|client2eventMesh|from={}|to={}", "RequestReply", + EventMeshConstants.PROTOCOL_GRPC, EventMeshCloudEventUtils.getIp(request), + eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); + eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(); + + EventEmitter emitter = new EventEmitter<>(responseObserver); + threadPoolExecutor.submit(() -> { + RequestCloudEventProcessor requestMessageProcessor = new RequestCloudEventProcessor(eventMeshGrpcServer); + try { + requestMessageProcessor.process(request, emitter); + } catch (Exception e) { + log.error("Error code {}, error message {}", StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR.getRetCode(), + StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR.getErrMsg(), e); + ServiceUtils.sendStreamResponseCompleted(request, StatusCode.EVENTMESH_REQUEST_REPLY_MSG_ERR, e.getMessage(), emitter); + } + }); + } + + /** + *
+     * publish batch event
+     * 
+ * + * @param request + * @param responseObserver + */ + @Override + public void batchPublish(CloudEventBatch request, StreamObserver responseObserver) { + log.info("cmd={}|{}|client2eventMesh|from={}|to={}", "BatchPublish", + EventMeshConstants.PROTOCOL_GRPC, null, + eventMeshGrpcServer.getEventMeshGrpcConfiguration().getEventMeshIp()); + eventMeshGrpcServer.getMetricsMonitor().recordReceiveMsgFromClient(request.getEventsCount()); + + EventEmitter emitter = new EventEmitter<>(responseObserver); + threadPoolExecutor.submit(() -> { + BatchPublishCloudEventProcessor batchPublishMessageProcessor = new BatchPublishCloudEventProcessor(eventMeshGrpcServer); + try { + batchPublishMessageProcessor.process(request, emitter); + } catch (Exception e) { + log.error("Error code {}, error message {}", StatusCode.EVENTMESH_BATCH_PUBLISH_ERR.getRetCode(), + StatusCode.EVENTMESH_BATCH_PUBLISH_ERR.getErrMsg(), e); + ServiceUtils.sendResponseCompleted(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 index f0c20ac91a..c59c7e3570 100644 --- 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 @@ -17,81 +17,137 @@ package org.apache.eventmesh.runtime.core.protocol.grpc.service; +import org.apache.eventmesh.common.protocol.HeartbeatItem; +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.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; +import org.apache.eventmesh.common.protocol.grpc.common.ProtoSupport; +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.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.common.utils.RandomStringUtils; import org.apache.eventmesh.runtime.constants.EventMeshConstants; -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; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.List; +import java.util.Objects; + +import io.cloudevents.SpecVersion; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; 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 validateCloudEventAttributes(CloudEvent cloudEvent) { + return StringUtils.isNotEmpty(EventMeshCloudEventUtils.getIdc(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getEnv(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getIp(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getPid(cloudEvent)) + && StringUtils.isNumeric(EventMeshCloudEventUtils.getPid(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getSys(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getUserName(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getPassword(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getLanguage(cloudEvent)); } - 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 validateCloudEventBatchAttributes(CloudEventBatch cloudEventBatch) { + if (null == cloudEventBatch || cloudEventBatch.getEventsCount() < 1) { + return false; + } + List eventsList = cloudEventBatch.getEventsList(); + for (CloudEvent cloudEvent : eventsList) { + if (validateCloudEventAttributes(cloudEvent)) { + continue; + } + return false; + } + return true; } - public static boolean validateBatchMessage(BatchMessage batchMessage) { - if (StringUtils.isEmpty(batchMessage.getTopic()) || StringUtils.isEmpty(batchMessage.getProducerGroup())) { + public static boolean validateCloudEventData(CloudEvent cloudEvent) { + boolean flag = StringUtils.isNotEmpty(EventMeshCloudEventUtils.getUniqueId(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getProducerGroup(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getSubject(cloudEvent)) + && StringUtils.isNotEmpty(EventMeshCloudEventUtils.getTtl(cloudEvent)); + if (!flag) { 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; + final String dataContentType = EventMeshCloudEventUtils.getDataContentType(cloudEvent); + if (ProtoSupport.isTextContent(dataContentType)) { + return flag && (StringUtils.isNotEmpty(cloudEvent.getTextData())); + } + if (ProtoSupport.isProtoContent(dataContentType)) { + return flag && (cloudEvent.getProtoData() != Any.getDefaultInstance()); + } + + return flag && (cloudEvent.getBinaryData() != ByteString.EMPTY); + } + + public static boolean validateCloudEventBatchData(CloudEventBatch cloudEventBatch) { + if (null == cloudEventBatch || cloudEventBatch.getEventsCount() < 1) { + return false; + } + List eventsList = cloudEventBatch.getEventsList(); + for (CloudEvent cloudEvent : eventsList) { + if (validateCloudEventData(cloudEvent)) { + continue; } + return false; } return true; } - public static boolean validateSubscription(GrpcType grpcType, Subscription subscription) { - if (GrpcType.WEBHOOK == grpcType && StringUtils.isEmpty(subscription.getUrl())) { + public static boolean validateSubscription(GrpcType grpcType, CloudEvent subscription) { + if (GrpcType.WEBHOOK == grpcType && StringUtils.isEmpty(EventMeshCloudEventUtils.getURL(subscription))) { return false; } - if (CollectionUtils.isEmpty(subscription.getSubscriptionItemsList()) - || StringUtils.isEmpty(subscription.getConsumerGroup())) { + List subscriptionItems = JsonUtils.parseTypeReferenceObject(subscription.getTextData(), + new TypeReference>() { + }); + if (CollectionUtils.isEmpty(subscriptionItems) + || StringUtils.isEmpty(EventMeshCloudEventUtils.getConsumerGroup(subscription))) { return false; } - for (Subscription.SubscriptionItem item : subscription.getSubscriptionItemsList()) { + for (SubscriptionItem item : subscriptionItems) { if (StringUtils.isEmpty(item.getTopic()) - || item.getMode() == Subscription.SubscriptionItem.SubscriptionMode.UNRECOGNIZED - || item.getType() == Subscription.SubscriptionItem.SubscriptionType.UNRECOGNIZED) { + || item.getMode() == SubscriptionMode.UNRECOGNIZED + || item.getType() == SubscriptionType.UNRECOGNIZED) { return false; } } return true; } - public static boolean validateHeartBeat(Heartbeat heartbeat) { - if (ClientType.SUB == heartbeat.getClientType() && StringUtils.isEmpty(heartbeat.getConsumerGroup())) { + public static boolean validateHeartBeat(CloudEvent heartbeat) { + org.apache.eventmesh.common.protocol.grpc.common.ClientType clientType = EventMeshCloudEventUtils.getClientType(heartbeat); + if (org.apache.eventmesh.common.protocol.grpc.common.ClientType.SUB == clientType && StringUtils.isEmpty( + EventMeshCloudEventUtils.getConsumerGroup(heartbeat))) { return false; } - if (ClientType.PUB == heartbeat.getClientType() && StringUtils.isEmpty(heartbeat.getProducerGroup())) { + if (org.apache.eventmesh.common.protocol.grpc.common.ClientType.PUB == clientType && StringUtils.isEmpty( + EventMeshCloudEventUtils.getProducerGroup(heartbeat))) { return false; } - for (Heartbeat.HeartbeatItem item : heartbeat.getHeartbeatItemsList()) { + List heartbeatItems = JsonUtils.parseTypeReferenceObject(heartbeat.getTextData(), + new TypeReference>() { + }); + Objects.requireNonNull(heartbeatItems, "heartbeatItems can't be null"); + for (HeartbeatItem item : heartbeatItems) { if (StringUtils.isEmpty(item.getTopic())) { return false; } @@ -99,58 +155,113 @@ public static boolean validateHeartBeat(Heartbeat heartbeat) { 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); + /** + * Sends a completed response event to the given EventEmitter. + * + * @param code The status code for the response. + * @param message The message for the response. + * @param emitter The EventEmitter to send the response event to. + */ + public static void sendResponseCompleted(StatusCode code, String message, EventEmitter emitter) { + + Instant instant = now(); + CloudEvent.Builder builder = CloudEvent.newBuilder().setId(RandomStringUtils.generateUUID()).setSpecVersion(SpecVersion.V1.toString()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_CODE, CloudEventAttributeValue.newBuilder().setCeString(code.getRetCode()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_MESSAGE, + CloudEventAttributeValue.newBuilder().setCeString(code.getErrMsg() + EventMeshConstants.BLANK_SPACE + message).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_TIME, CloudEventAttributeValue.newBuilder() + .setCeTimestamp(Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build()).build()); + + emitter.onNext(builder.build()); emitter.onCompleted(); } - public static void sendRespAndDone(StatusCode code, String message, EventEmitter emitter) { - Response response = Response.newBuilder() - .setRespCode(code.getRetCode()) - .setRespMsg(code.getErrMsg() + EventMeshConstants.BLANK_SPACE + message) - .setRespTime(String.valueOf(System.currentTimeMillis())) - .build(); - emitter.onNext(response); + /** + * Sends a completed response event to the emitter. + * + * @param code The status code of the response + * @param emitter The emitter to send the event to + */ + public static void sendResponseCompleted(StatusCode code, EventEmitter emitter) { + Instant instant = now(); + CloudEvent.Builder builder = CloudEvent.newBuilder().setSpecVersion(SpecVersion.V1.toString()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_CODE, CloudEventAttributeValue.newBuilder().setCeString(code.getRetCode()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_MESSAGE, CloudEventAttributeValue.newBuilder().setCeString(code.getErrMsg()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_TIME, CloudEventAttributeValue.newBuilder() + .setCeTimestamp(Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build()).build()); + emitter.onNext(builder.build()); emitter.onCompleted(); } - public static void sendStreamResp(RequestHeader header, StatusCode code, String message, - EventEmitter emitter) { - Map resp = new HashMap<>(); - resp.put(EventMeshConstants.RESP_CODE, code.getRetCode()); - resp.put(EventMeshConstants.RESP_MSG, code.getErrMsg() + EventMeshConstants.BLANK_SPACE + message); - - SimpleMessage simpleMessage = SimpleMessage.newBuilder() - .setHeader(header) - .setContent(JsonUtils.toJSONString(resp)) - .build(); - - emitter.onNext(simpleMessage); + /** + * Sends a completed response event to the emitter for a stream. + * + * @param cloudEvent The original CloudEvent + * @param code The status code of the response + * @param emitter The emitter to send the event to + */ + public static void sendStreamResponseCompleted(CloudEvent cloudEvent, StatusCode code, EventEmitter emitter) { + sendStreamResponse(cloudEvent, code, emitter); + emitter.onCompleted(); } - public static void sendStreamRespAndDone(RequestHeader header, StatusCode code, String message, - EventEmitter emitter) { - sendStreamResp(header, code, message, emitter); + /** + * Sends a completed response event to the emitter for a stream with a custom message. + * + * @param cloudEvent The original CloudEvent + * @param code The status code of the response + * @param message The custom message for the response + * @param emitter The emitter to send the event to + */ + public static void sendStreamResponseCompleted(CloudEvent cloudEvent, StatusCode code, String message, EventEmitter emitter) { + sendStreamResponse(cloudEvent, code, message, emitter); emitter.onCompleted(); } - public static void sendStreamRespAndDone(RequestHeader header, StatusCode code, - EventEmitter emitter) { - Map resp = new HashMap<>(); - resp.put(EventMeshConstants.RESP_CODE, code.getRetCode()); - resp.put(EventMeshConstants.RESP_MSG, code.getErrMsg()); + /** + * Sends a response event to the emitter for a stream. + * + * @param cloudEvent The original CloudEvent + * @param code The status code of the response + * @param emitter The emitter to send the event to + */ + public static void sendStreamResponse(CloudEvent cloudEvent, StatusCode code, EventEmitter emitter) { + Instant instant = now(); + CloudEvent.Builder builder = CloudEvent.newBuilder(cloudEvent) + .putAttributes(ProtocolKey.GRPC_RESPONSE_CODE, CloudEventAttributeValue.newBuilder().setCeString(code.getRetCode()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_MESSAGE, CloudEventAttributeValue.newBuilder().setCeString(code.getErrMsg()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_TIME, CloudEventAttributeValue.newBuilder() + .setCeTimestamp(Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build()).build()); - SimpleMessage simpleMessage = SimpleMessage.newBuilder() - .setHeader(header) - .setContent(JsonUtils.toJSONString(resp)) - .build(); + emitter.onNext(builder.build()); + } - emitter.onNext(simpleMessage); - emitter.onCompleted(); + /** + * Sends a response event to the emitter for a stream with a custom message. + * + * @param cloudEvent The original CloudEvent + * @param code The status code of the response + * @param message The custom message for the response + * @param emitter The emitter to send the event to + */ + public static void sendStreamResponse(CloudEvent cloudEvent, StatusCode code, String message, EventEmitter emitter) { + Instant instant = OffsetDateTime.now().toInstant(); + CloudEvent.Builder builder = CloudEvent.newBuilder(cloudEvent) + .putAttributes(ProtocolKey.GRPC_RESPONSE_CODE, CloudEventAttributeValue.newBuilder().setCeString(code.getRetCode()).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_MESSAGE, + CloudEventAttributeValue.newBuilder().setCeString(StringUtils.isEmpty(message) ? code.getErrMsg() : message).build()) + .putAttributes(ProtocolKey.GRPC_RESPONSE_TIME, CloudEventAttributeValue.newBuilder() + .setCeTimestamp(Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build()).build()); + + emitter.onNext(builder.build()); + } + + /** + * Returns the current instant. + * + * @return The current instant + */ + private static Instant now() { + return OffsetDateTime.of(LocalDateTime.now(ZoneId.systemDefault()), ZoneOffset.UTC).toInstant(); } } 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 index ee0ca34cb4..e60f1687ac 100644 --- 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 @@ -27,7 +27,6 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; - import com.google.common.eventbus.Subscribe; import lombok.extern.slf4j.Slf4j; @@ -42,7 +41,6 @@ public class ConsumerManager { */ private ConcurrentHashMap consumerTable = new ConcurrentHashMap<>(64); - public ConsumerManager(final EventMeshHTTPServer eventMeshHTTPServer) { this.eventMeshHTTPServer = eventMeshHTTPServer; } @@ -183,7 +181,7 @@ public void handleConsumerGroupTopicConfChangeEvent(ConsumerGroupTopicConfChange break; } default: - //do nothing + // do nothing } } catch (Exception ex) { log.error("onChange event:{} err", event, ex); @@ -206,7 +204,7 @@ public void handleConsumerGroupStateEvent(ConsumerGroupStateEvent event) { delConsumer(event.getConsumerGroup()); break; default: - //do nothing + // do nothing } } catch (Exception ex) { log.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 index 31fd31b598..1f6b974b31 100644 --- 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 @@ -28,6 +28,7 @@ import org.apache.eventmesh.api.EventMeshAsyncConsumeContext; import org.apache.eventmesh.api.SendCallback; import org.apache.eventmesh.api.SendResult; +import org.apache.eventmesh.api.TopicNameHelper; import org.apache.eventmesh.api.exception.OnExceptionContext; import org.apache.eventmesh.common.protocol.SubscriptionItem; import org.apache.eventmesh.common.protocol.SubscriptionMode; @@ -37,18 +38,20 @@ 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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; import org.apache.eventmesh.runtime.util.EventMeshUtil; import org.apache.eventmesh.runtime.util.TraceUtils; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; 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.Optional; import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; @@ -59,12 +62,13 @@ import io.cloudevents.core.builder.CloudEventBuilder; import io.opentelemetry.api.trace.Span; - import lombok.extern.slf4j.Slf4j; @Slf4j public class EventMeshConsumer { + public static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); + private final EventMeshHTTPServer eventMeshHTTPServer; private final AtomicBoolean started4Persistent = new AtomicBoolean(Boolean.FALSE); @@ -75,8 +79,6 @@ public class EventMeshConsumer { private final AtomicBoolean inited4Broadcast = new AtomicBoolean(Boolean.FALSE); - public final Logger messageLogger = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); - private ConsumerGroupConf consumerGroupConf; private final MQConsumerWrapper persistentMqConsumer; @@ -110,35 +112,42 @@ public synchronized void init() throws Exception { EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), EventMeshTraceConstants.TRACE_DOWNSTREAM_EVENTMESH_SERVER_SPAN, false); try { + Optional topicNameHelper = + Optional.ofNullable(EventMeshExtensionFactory.getExtension(TopicNameHelper.class, + eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshStoragePluginType())); String topic = event.getSubject(); - String bizSeqNo = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.BIZSEQNO)).toString(); - String uniqueId = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.UNIQUEID)).toString(); + String bizSeqNo = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.BIZSEQNO.getKey())).toString(); + String uniqueId = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.UNIQUEID.getKey())).toString(); event = CloudEventBuilder.from(event) .withExtension(EventMeshConstants.REQ_MQ2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) .withExtension(EventMeshConstants.REQ_RECEIVE_EVENTMESH_IP, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshServerIp()) .build(); - if (messageLogger.isDebugEnabled()) { - messageLogger.debug("message|mq2eventMesh|topic={}|event={}", topic, event); + if (MESSAGE_LOGGER.isDebugEnabled()) { + MESSAGE_LOGGER.debug("message|mq2eventMesh|topic={}|event={}", topic, event); } else { - messageLogger.info("message|mq2eventMesh|topic={}|bizSeqNo={}|uniqueId={}", topic, bizSeqNo, uniqueId); + MESSAGE_LOGGER.info("message|mq2eventMesh|topic={}|bizSeqNo={}|uniqueId={}", topic, bizSeqNo, uniqueId); } + if (topicNameHelper.isPresent() && topicNameHelper.get().isRetryTopic(topic)) { + topic = String.valueOf(event.getExtension(ProtocolKey.TOPIC)); + } ConsumerGroupTopicConf currentTopicConfig = MapUtils.getObject(consumerGroupConf.getConsumerGroupTopicConf(), topic, null); EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = (EventMeshAsyncConsumeContext) context; if (currentTopicConfig == null) { - log.error("no topicConfig found, consumerGroup:{} topic:{}", - consumerGroupConf.getConsumerGroup(), topic); try { sendMessageBack(event, uniqueId, bizSeqNo); - eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); - return; + log.warn("no ConsumerGroupTopicConf found, sendMessageBack success, consumerGroup:{}, topic:{}, bizSeqNo={}, uniqueId={}", + consumerGroupConf.getConsumerGroup(), topic, bizSeqNo, uniqueId); } catch (Exception ex) { - //ignore + log.warn("sendMessageBack fail, consumerGroup:{}, topic:{}, bizSeqNo={}, uniqueId={}", + consumerGroupConf.getConsumerGroup(), topic, bizSeqNo, uniqueId, ex); } + eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); + return; } SubscriptionItem subscriptionItem = @@ -156,7 +165,8 @@ public synchronized void init() throws Exception { try { sendMessageBack(event, uniqueId, bizSeqNo); } catch (Exception e) { - //ignore + // ignore + log.warn("sendMessageBack fail,topic:{}, bizSeqNo={}, uniqueId={}", topic, bizSeqNo, uniqueId, e); } eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); } @@ -166,7 +176,7 @@ public synchronized void init() throws Exception { }; persistentMqConsumer.registerEventListener(clusterEventListener); - //broadcast consumer + // broadcast consumer Properties broadcastKeyValue = new Properties(); broadcastKeyValue.put(IS_BROADCAST, "true"); broadcastKeyValue.put(CONSUMER_GROUP, consumerGroupConf.getConsumerGroup()); @@ -193,15 +203,13 @@ public synchronized void init() throws Exception { .build(); String topic = event.getSubject(); - String bizSeqNo = getEventExtension(event, ProtocolKey.ClientInstanceKey.BIZSEQNO); - String uniqueId = getEventExtension(event, ProtocolKey.ClientInstanceKey.UNIQUEID); + String bizSeqNo = getEventExtension(event, ProtocolKey.ClientInstanceKey.BIZSEQNO.getKey()); + String uniqueId = getEventExtension(event, ProtocolKey.ClientInstanceKey.UNIQUEID.getKey()); - if (messageLogger.isDebugEnabled()) { - messageLogger.debug("message|mq2eventMesh|topic={}|msg={}", topic, event); + if (MESSAGE_LOGGER.isDebugEnabled()) { + MESSAGE_LOGGER.debug("message|mq2eventMesh|topic={}|msg={}", topic, event); } else { - messageLogger.info("message|mq2eventMesh|topic={}|bizSeqNo={}|uniqueId={}", - topic, bizSeqNo, - uniqueId); + MESSAGE_LOGGER.info("message|mq2eventMesh|topic={}|bizSeqNo={}|uniqueId={}", topic, bizSeqNo, uniqueId); } ConsumerGroupTopicConf currentTopicConfig = MapUtils.getObject( @@ -217,7 +225,7 @@ public synchronized void init() throws Exception { eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); return; } catch (Exception ex) { - //ignore + // ignore } } @@ -238,7 +246,7 @@ public synchronized void init() throws Exception { try { sendMessageBack(event, uniqueId, bizSeqNo); } catch (Exception e) { - //ignore + // ignore } eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); } @@ -311,8 +319,7 @@ public EventMeshHTTPServer getEventMeshHTTPServer() { public void sendMessageBack(final CloudEvent event, final String uniqueId, String bizSeqNo) throws Exception { - EventMeshProducer sendMessageBack - = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(consumerGroupConf.getConsumerGroup()); + EventMeshProducer sendMessageBack = eventMeshHTTPServer.getProducerManager().getEventMeshProducer(consumerGroupConf.getConsumerGroup()); if (sendMessageBack == null) { log.warn("consumer:{} consume fail, sendMessageBack, bizSeqNo:{}, uniqueId:{}", @@ -324,6 +331,7 @@ public void sendMessageBack(final CloudEvent event, final String uniqueId, Strin eventMeshHTTPServer); sendMessageBack.send(sendMessageBackContext, new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { } 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 index e2da611851..c4046827a7 100644 --- 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 @@ -24,6 +24,7 @@ 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.consumer.HandleMessageContext; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; @@ -33,13 +34,17 @@ import java.util.Map; import java.util.Objects; -import io.cloudevents.CloudEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import io.cloudevents.CloudEvent; import lombok.extern.slf4j.Slf4j; @Slf4j -public class HandleMsgContext { +public class HandleMsgContext implements HandleMessageContext { + + public static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); private String msgRandomNo; @@ -205,9 +210,9 @@ public EventMeshHTTPServer getEventMeshHTTPServer() { public void finish() { if (Objects.nonNull(eventMeshConsumer) && Objects.nonNull(context) && Objects.nonNull(event)) { - if (log.isDebugEnabled()) { - log.debug("messageAcked|topic={}|event={}", topic, event); - } + MESSAGE_LOGGER.info("messageAcked|group={}|topic={}|bizSeq={}|uniqId={}|msgRandomNo={}|queueId={}|queueOffset={}", + consumerGroup, topic, bizSeqNo, uniqueId, msgRandomNo, event.getExtension(Constants.PROPERTY_MESSAGE_QUEUE_ID), + event.getExtension(Constants.PROPERTY_MESSAGE_QUEUE_OFFSET)); eventMeshConsumer.updateOffset(topic, subscriptionItem.getMode(), Collections.singletonList(event), context); } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/HttpClientGroupMapping.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/HttpClientGroupMapping.java index b62f1f129b..004c9ee3b9 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/HttpClientGroupMapping.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/consumer/HttpClientGroupMapping.java @@ -17,7 +17,6 @@ package org.apache.eventmesh.runtime.core.protocol.http.consumer; - import org.apache.eventmesh.common.protocol.SubscriptionItem; import org.apache.eventmesh.common.protocol.http.header.client.SubscribeRequestHeader; import org.apache.eventmesh.common.protocol.http.header.client.UnSubscribeRequestHeader; @@ -45,16 +44,21 @@ import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; - import lombok.extern.slf4j.Slf4j; @Slf4j public final class HttpClientGroupMapping { - private final transient Map localConsumerGroupMapping = + /** + * key: group + */ + private final transient Map localConsumerGroupMapping = new ConcurrentHashMap<>(); - private final transient Map> localClientInfoMapping = + /** + * key: group@topic + */ + private final transient Map> localClientInfoMapping = new ConcurrentHashMap<>(); private final transient Set localTopicSet = new HashSet(16); @@ -158,8 +162,8 @@ public Map prepareMetaData() { final Map consumerGroupTopicMetadataMap = new HashMap<>(1 << 4); - for (final Map.Entry consumerGroupTopicConfEntry - : consumerGroupConf.getConsumerGroupTopicConf().entrySet()) { + for (final Map.Entry consumerGroupTopicConfEntry : consumerGroupConf.getConsumerGroupTopicConf() + .entrySet()) { final ConsumerGroupTopicConf consumerGroupTopicConf = consumerGroupTopicConfEntry.getValue(); final ConsumerGroupTopicMetadata consumerGroupTopicMetadata = new ConsumerGroupTopicMetadata(); consumerGroupTopicMetadata.setConsumerGroup(consumerGroupTopicConf.getConsumerGroup()); @@ -233,7 +237,7 @@ private boolean addSubscriptionByTopic(final String consumerGroup, final String final Map map = consumerGroupConf.getConsumerGroupTopicConf(); if (!map.containsKey(subTopic.getTopic())) { - //If there are multiple topics, append it + // If there are multiple topics, append it final ConsumerGroupTopicConf newTopicConf = new ConsumerGroupTopicConf(); newTopicConf.setConsumerGroup(consumerGroup); newTopicConf.setTopic(subTopic.getTopic()); @@ -250,15 +254,9 @@ private boolean addSubscriptionByTopic(final String consumerGroup, final String final ConsumerGroupTopicConf currentTopicConf = map.get(subTopic.getTopic()); if (!currentTopicConf.getUrls().add(url)) { isChange = true; - if (log.isInfoEnabled()) { - log.info("add subscribe success, group:{}, url:{} , topic:{}", consumerGroup, url, - subTopic.getTopic()); - } + log.info("add subscribe success, group:{}, url:{} , topic:{}", consumerGroup, url, subTopic.getTopic()); } else { - if (log.isWarnEnabled()) { - log.warn("The group has subscribed, group:{}, url:{} , topic:{}", consumerGroup, url, - subTopic.getTopic()); - } + log.warn("The group has subscribed, group:{}, url:{} , topic:{}", consumerGroup, url, subTopic.getTopic()); } if (!currentTopicConf.getIdcUrls().containsKey(clientIdc)) { @@ -266,24 +264,18 @@ private boolean addSubscriptionByTopic(final String consumerGroup, final String urls.add(url); currentTopicConf.getIdcUrls().put(clientIdc, urls); isChange = true; - if (log.isInfoEnabled()) { - log.info("add url to idcUrlMap success, group:{}, url:{}, topic:{}, clientIdc:{}", - consumerGroup, url, subTopic.getTopic(), clientIdc); - } + log.info("add url to idcUrlMap success, group:{}, url:{}, topic:{}, clientIdc:{}", + consumerGroup, url, subTopic.getTopic(), clientIdc); } else { final Set tmpSet = new HashSet<>(currentTopicConf.getIdcUrls().get(clientIdc)); if (!tmpSet.contains(url)) { currentTopicConf.getIdcUrls().get(clientIdc).add(url); isChange = true; - if (log.isInfoEnabled()) { - log.info("add url to idcUrlMap success, group:{}, url:{}, topic:{}, clientIdc:{}", - consumerGroup, url, subTopic.getTopic(), clientIdc); - } + log.info("add url to idcUrlMap success, group:{}, url:{}, topic:{}, clientIdc:{}", + consumerGroup, url, subTopic.getTopic(), clientIdc); } else { - if (log.isWarnEnabled()) { - log.warn("The idcUrlMap has contains url, group:{}, url:{} , topic:{}, clientIdc:{}", - consumerGroup, url, subTopic.getTopic(), clientIdc); - } + log.warn("The idcUrlMap has contains url, group:{}, url:{} , topic:{}, clientIdc:{}", + consumerGroup, url, subTopic.getTopic(), clientIdc); } } } @@ -302,69 +294,46 @@ private boolean removeSubscriptionByTopic(final String consumerGroup, final Stri final ConsumerGroupConf consumerGroupConf = localConsumerGroupMapping.get(consumerGroup); if (consumerGroupConf == null) { - if (log.isWarnEnabled()) { - log.warn("unsubscribe fail, the current mesh does not have group subscriptionInfo, group:{}, url:{}", - consumerGroup, unSubscribeUrl); - } + log.warn("unsubscribe fail, the current mesh does not have group subscriptionInfo, group:{}, url:{}", consumerGroup, unSubscribeUrl); return false; } final ConsumerGroupTopicConf consumerGroupTopicConf = consumerGroupConf.getConsumerGroupTopicConf().get(unSubTopic); if (consumerGroupTopicConf == null) { - if (log.isWarnEnabled()) { - log.warn( - "unsubscribe fail, the current mesh does not have group-topic subscriptionInfo, group:{}, topic:{}, url:{}", - consumerGroup, unSubTopic, unSubscribeUrl); - } + log.warn("unsubscribe fail, the current mesh does not have group-topic subscriptionInfo, group:{}, topic:{}, url:{}", + consumerGroup, unSubTopic, unSubscribeUrl); return false; } if (consumerGroupTopicConf.getUrls().remove(unSubscribeUrl)) { isChange = true; - if (log.isInfoEnabled()) { - log.info("remove url success, group:{}, topic:{}, url:{}", consumerGroup, unSubTopic, unSubscribeUrl); - } + log.info("remove url success, group:{}, topic:{}, url:{}", consumerGroup, unSubTopic, unSubscribeUrl); } else { - if (log.isWarnEnabled()) { - log.warn("remove url fail, not exist subscrition of this url, group:{}, topic:{}, url:{}", - consumerGroup, unSubTopic, unSubscribeUrl); - } + log.warn("remove url fail, not exist subscrition of this url, group:{}, topic:{}, url:{}", consumerGroup, unSubTopic, unSubscribeUrl); } if (consumerGroupTopicConf.getIdcUrls().containsKey(clientIdc)) { if (consumerGroupTopicConf.getIdcUrls().get(clientIdc).remove(unSubscribeUrl)) { isChange = true; - if (log.isInfoEnabled()) { - log.info("remove url from idcUrlMap success, group:{}, topic:{}, url:{}, clientIdc:{}", - consumerGroup, unSubTopic, unSubscribeUrl, clientIdc); - } + log.info("remove url from idcUrlMap success, group:{}, topic:{}, url:{}, clientIdc:{}", + consumerGroup, unSubTopic, unSubscribeUrl, clientIdc); } else { - if (log.isWarnEnabled()) { - log.warn( - "remove url from idcUrlMap fail, not exist subscriber of this url, group:{}, topic:{}, url:{}, clientIdc:{}", - consumerGroup, unSubTopic, unSubscribeUrl, clientIdc); - } - } - } else { - if (log.isWarnEnabled()) { - log.warn( - "remove url from idcUrlMap fail,not exist subscrition of this idc , group:{}, topic:{}, url:{}, clientIdc:{}", + log.warn("remove url from idcUrlMap fail, not exist subscriber of this url, group:{}, topic:{}, url:{}, clientIdc:{}", consumerGroup, unSubTopic, unSubscribeUrl, clientIdc); } + } else { + log.warn("remove url from idcUrlMap fail,not exist subscrition of this idc , group:{}, topic:{}, url:{}, clientIdc:{}", + consumerGroup, unSubTopic, unSubscribeUrl, clientIdc); } if (isChange && CollectionUtils.isEmpty(consumerGroupTopicConf.getUrls())) { consumerGroupConf.getConsumerGroupTopicConf().remove(unSubTopic); - if (log.isInfoEnabled()) { - log.info("group unsubscribe topic success,group:{}, topic:{}", consumerGroup, unSubTopic); - } + log.info("group unsubscribe topic success,group:{}, topic:{}", consumerGroup, unSubTopic); } if (isChange && MapUtils.isEmpty(consumerGroupConf.getConsumerGroupTopicConf())) { localConsumerGroupMapping.remove(consumerGroup); - if (log.isInfoEnabled()) { - log.info("group unsubscribe success,group:{}", consumerGroup); - } + log.info("group unsubscribe success,group:{}", consumerGroup); } return isChange; } @@ -389,12 +358,13 @@ private void registerClientForSub(final SubscribeRequestHeader subscribeRequestH client.setLastUpTime(new Date()); final String groupTopicKey = client.getConsumerGroup() + "@" + client.getTopic(); List localClients = localClientInfoMapping.computeIfAbsent( - groupTopicKey, key -> Collections.unmodifiableList(new ArrayList() { - private static final long serialVersionUID = -529919988844134656L; - { - add(client); - } - })); + groupTopicKey, key -> Collections.unmodifiableList(new ArrayList() { + + private static final long serialVersionUID = -529919988844134656L; + { + add(client); + } + })); localClients.stream().filter(o -> StringUtils.equals(o.getUrl(), client.getUrl())).findFirst() .ifPresent(o -> o.setLastUpTime(client.getLastUpTime())); } @@ -417,9 +387,9 @@ public boolean removeSubscriptionForRequestCode(final UnSubscribeRequestHeader u for (final String unSubTopic : unSubTopicList) { isChange = isChange || removeSubscriptionByTopic(consumerGroup, - unSubscribeUrl, - unSubscribeRequestHeader.getIdc(), - unSubTopic); + unSubscribeUrl, + unSubscribeRequestHeader.getIdc(), + unSubTopic); } } finally { READ_WRITE_LOCK.writeLock().unlock(); @@ -449,15 +419,15 @@ private void registerClientForUnsub(final UnSubscribeRequestHeader unSubscribeRe client.setLastUpTime(new Date()); final String groupTopicKey = client.getConsumerGroup() + "@" + client.getTopic(); List localClients = localClientInfoMapping.computeIfAbsent( - groupTopicKey, key -> Collections.unmodifiableList(new ArrayList() { - private static final long serialVersionUID = -529919988844134656L; - { - add(client); - } - })); + groupTopicKey, key -> Collections.unmodifiableList(new ArrayList() { + + private static final long serialVersionUID = -529919988844134656L; + { + add(client); + } + })); localClients.stream().filter(o -> StringUtils.equals(o.getUrl(), client.getUrl())).findFirst() .ifPresent(o -> o.setLastUpTime(client.getLastUpTime())); } } } - 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 index d0b11f9729..e9e9751301 100644 --- 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 @@ -34,7 +34,6 @@ import lombok.RequiredArgsConstructor; - @RequiredArgsConstructor public class AdminShutdownProcessor implements HttpRequestProcessor { @@ -48,7 +47,7 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get(Integer.valueOf(asyncContext.getRequest().getRequestCode())), - EventMeshConstants.PROTOCOL_HTTP, remoteAddr, IPUtils.getLocalAddress()); + EventMeshConstants.PROTOCOL_HTTP, remoteAddr, IPUtils.getLocalAddress()); eventMeshServer.shutdown(); 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 index 501d5e3c52..d641efb537 100644 --- 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 @@ -25,6 +25,7 @@ /** * async http processor */ + public interface AsyncHttpProcessor extends HttpProcessor { default HttpResponse handler(HttpRequest httpRequest) { 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 index 22a05f37fb..5baf65515b 100644 --- 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 @@ -41,8 +41,8 @@ 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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; import org.apache.eventmesh.runtime.util.RemotingHelper; import org.apache.commons.collections4.CollectionUtils; @@ -63,13 +63,15 @@ import io.cloudevents.core.builder.CloudEventBuilder; import io.netty.channel.ChannelHandlerContext; +import com.google.common.base.Stopwatch; + public class BatchSendMessageProcessor implements HttpRequestProcessor { - private final Logger cmdLogger = LoggerFactory.getLogger(EventMeshConstants.CMD); + private static final Logger CMD_LOGGER = LoggerFactory.getLogger(EventMeshConstants.CMD); + + private static final Logger ACL_LOGGER = LoggerFactory.getLogger(EventMeshConstants.ACL); - private final Logger aclLogger = LoggerFactory.getLogger(EventMeshConstants.ACL); - - private final Logger batchMessageLogger = LoggerFactory.getLogger("batchMessage"); + private static final Logger BATCH_MSG_LOGGER = LoggerFactory.getLogger(EventMeshConstants.BATCH_MSG); private final EventMeshHTTPServer eventMeshHTTPServer; @@ -83,23 +85,17 @@ public BatchSendMessageProcessor(final EventMeshHTTPServer eventMeshHTTPServer) @Override public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) throws Exception { - HttpCommand responseEventMeshCommand; String localAddress = IPUtils.getLocalAddress(); HttpCommand request = asyncContext.getRequest(); - cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get( - Integer.valueOf(request.getRequestCode())), - EventMeshConstants.PROTOCOL_HTTP, - RemotingHelper.parseChannelRemoteAddr(ctx.channel()), localAddress); + CMD_LOGGER.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get(Integer.valueOf(request.getRequestCode())), + EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), localAddress); - SendMessageBatchRequestHeader sendMessageBatchRequestHeader = - (SendMessageBatchRequestHeader) request.getHeader(); + SendMessageBatchRequestHeader sendMessageBatchRequestHeader = (SendMessageBatchRequestHeader) request.getHeader(); EventMeshHTTPConfiguration httpConfiguration = eventMeshHTTPServer.getEventMeshHttpConfiguration(); - SendMessageBatchResponseHeader sendMessageBatchResponseHeader = - SendMessageBatchResponseHeader.buildHeader(Integer.valueOf(request.getRequestCode()), - httpConfiguration.getEventMeshCluster(), - localAddress, httpConfiguration.getEventMeshEnv(), - httpConfiguration.getEventMeshIDC()); + SendMessageBatchResponseHeader sendMessageBatchResponseHeader = SendMessageBatchResponseHeader.buildHeader( + Integer.valueOf(request.getRequestCode()), httpConfiguration.getEventMeshCluster(), localAddress, httpConfiguration.getEventMeshEnv(), + httpConfiguration.getEventMeshIDC()); String protocolType = sendMessageBatchRequestHeader.getProtocolType(); ProtocolAdaptor httpCommandProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); @@ -107,7 +103,7 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext if (CollectionUtils.isEmpty(eventList)) { completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageBatchResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageBatchResponseBody.class); return; } @@ -116,44 +112,37 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext int eventSize = eventList.size(); if (eventSize > httpConfiguration.getEventMeshEventBatchSize()) { - batchMessageLogger.error("Event batch size exceeds the limit: {}", - httpConfiguration.getEventMeshEventBatchSize()); - completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, - "Event batch size exceeds the limit: " + httpConfiguration.getEventMeshEventBatchSize(), - SendMessageBatchResponseBody.class); + BATCH_MSG_LOGGER.error("Event batch size exceeds the limit: {}", httpConfiguration.getEventMeshEventBatchSize()); + completeResponse(request, asyncContext, sendMessageBatchResponseHeader, EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, + "Event batch size exceeds the limit: " + httpConfiguration.getEventMeshEventBatchSize(), SendMessageBatchResponseBody.class); return; } for (CloudEvent event : eventList) { - //validate event + // validate event if (!ObjectUtils.allNotNull(event.getSource(), event.getSpecVersion()) || StringUtils.isAnyBlank(event.getId(), event.getType(), event.getSubject())) { completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageBatchResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageBatchResponseBody.class); return; } String content = event.getData() == null ? "" : new String(event.getData().toBytes(), Constants.DEFAULT_CHARSET); if (content.length() > httpConfiguration.getEventMeshEventSize()) { - batchMessageLogger.error("Event size exceeds the limit: {}", - httpConfiguration.getEventMeshEventSize()); - completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, - "Event size exceeds the limit: " + httpConfiguration.getEventMeshEventSize(), - SendMessageBatchResponseBody.class); + BATCH_MSG_LOGGER.error("Event size exceeds the limit: {}", httpConfiguration.getEventMeshEventSize()); + completeResponse(request, asyncContext, sendMessageBatchResponseHeader, EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, + "Event size exceeds the limit: " + httpConfiguration.getEventMeshEventSize(), SendMessageBatchResponseBody.class); return; } - String idc = getExtension(event, ProtocolKey.ClientInstanceKey.IDC); - String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID); - String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS); + String idc = getExtension(event, ProtocolKey.ClientInstanceKey.IDC.getKey()); + String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID.getKey()); + String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS.getKey()); - //validate event-extension - if (StringUtils.isAnyBlank(idc, pid, sys) - || !StringUtils.isNumeric(pid)) { + // validate event-extension + if (StringUtils.isAnyBlank(idc, pid, sys) || !StringUtils.isNumeric(pid)) { completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageBatchResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageBatchResponseBody.class); return; } @@ -162,10 +151,9 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext eventSize = Integer.parseInt(getExtension(event, SendMessageBatchRequestBody.SIZE)); CloudEventData eventData = event.getData(); - if (eventData == null || StringUtils.isAnyBlank(batchId, producerGroup) - || eventSize != eventList.size()) { + if (eventData == null || StringUtils.isAnyBlank(batchId, producerGroup) || eventSize != eventList.size()) { completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageBatchResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageBatchResponseBody.class); return; } @@ -176,7 +164,7 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext .tryAcquire(eventSize, EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { summaryMetrics.recordSendBatchMsgDiscard(eventSize); completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR, null, SendMessageBatchResponseBody.class); + EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR, null, SendMessageBatchResponseBody.class); return; } @@ -186,34 +174,33 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext if (!batchEventMeshProducer.isStarted()) { completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR, null, SendMessageBatchResponseBody.class); + EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR, null, SendMessageBatchResponseBody.class); return; } - final long batchStartTime = System.currentTimeMillis(); - + final Stopwatch stopwatch = Stopwatch.createStarted(); String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); int requestCode = Integer.parseInt(request.getRequestCode()); - Map> topicBatchMessageMappings = new ConcurrentHashMap>(); + Map> topicBatchMessageMappings = new ConcurrentHashMap<>(); for (CloudEvent cloudEvent : eventList) { if (StringUtils.isBlank(cloudEvent.getSubject()) || cloudEvent.getData() == null) { continue; } - String user = getExtension(cloudEvent, ProtocolKey.ClientInstanceKey.USERNAME); - String pass = getExtension(cloudEvent, ProtocolKey.ClientInstanceKey.PASSWD); - String subsystem = getExtension(cloudEvent, ProtocolKey.ClientInstanceKey.SYS); + String user = getExtension(cloudEvent, ProtocolKey.ClientInstanceKey.USERNAME.getKey()); + String pass = getExtension(cloudEvent, ProtocolKey.ClientInstanceKey.PASSWD.getKey()); + String subsystem = getExtension(cloudEvent, ProtocolKey.ClientInstanceKey.SYS.getKey()); - //do acl check + // do acl check if (httpConfiguration.isEventMeshServerSecurityEnable()) { try { this.acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, cloudEvent.getSubject(), requestCode); } catch (Exception e) { completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_ACL_ERR, e.getMessage(), SendMessageBatchResponseBody.class); - aclLogger.warn("CLIENT HAS NO PERMISSION,BatchSendMessageProcessor send failed", e); + EventMeshRetCode.EVENTMESH_ACL_ERR, e.getMessage(), SendMessageBatchResponseBody.class); + ACL_LOGGER.warn("CLIENT HAS NO PERMISSION,BatchSendMessageProcessor send failed", e); return; } } @@ -236,18 +223,16 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext topicBatchMessageMappings.put(cloudEvent.getSubject(), tmp); } - if (batchMessageLogger.isDebugEnabled()) { - batchMessageLogger.debug("msg2MQMsg suc, event:{}", cloudEvent.getData()); - } + BATCH_MSG_LOGGER.debug("msg2MQMsg suc, event:{}", cloudEvent.getData()); } catch (Exception e) { - batchMessageLogger.error("msg2MQMsg err, event:{}", cloudEvent.getData(), e); + BATCH_MSG_LOGGER.error("msg2MQMsg err, event:{}", cloudEvent.getData(), e); } } if (CollectionUtils.isEmpty(eventList)) { completeResponse(request, asyncContext, sendMessageBatchResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageBatchResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageBatchResponseBody.class); return; } @@ -259,27 +244,26 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext // TODO: Implementation in API. Consider whether to put it in the plug-in. CloudEvent event = null; // TODO: Detect the maximum length of messages for different producers. - final SendMessageContext sendMessageContext = new SendMessageContext(batchId, event, batchEventMeshProducer, - eventMeshHTTPServer); - sendMessageContext.setEventList(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)); + BATCH_MSG_LOGGER.warn("", context.getException()); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); } }); } } else { for (CloudEvent event : eventList) { - final SendMessageContext sendMessageContext = new SendMessageContext(batchId, event, batchEventMeshProducer, - eventMeshHTTPServer); + final SendMessageContext sendMessageContext = new SendMessageContext(batchId, event, batchEventMeshProducer, eventMeshHTTPServer); batchEventMeshProducer.send(sendMessageContext, new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { @@ -287,21 +271,21 @@ public void onSuccess(SendResult sendResult) { @Override public void onException(OnExceptionContext context) { - batchMessageLogger.warn("", context.getException()); - eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + BATCH_MSG_LOGGER.warn("", context.getException()); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); } }); } } - long batchEndTime = System.currentTimeMillis(); - summaryMetrics.recordBatchSendMsgCost(batchEndTime - batchStartTime); - batchMessageLogger.debug("batchMessage|eventMesh2mq|REQ|ASYNC|batchId={}|send2MQCost={}ms|msgNum={}|topics={}", - batchId, batchEndTime - batchStartTime, eventSize, topicBatchMessageMappings.keySet()); + long elapsed = stopwatch.elapsed(TimeUnit.MILLISECONDS); + summaryMetrics.recordBatchSendMsgCost(elapsed); + BATCH_MSG_LOGGER.debug("batchMessage|eventMesh2mq|REQ|ASYNC|batchId={}|send2MQCost={}ms|msgNum={}|topics={}", + batchId, elapsed, eventSize, topicBatchMessageMappings.keySet()); completeResponse(request, asyncContext, sendMessageBatchResponseHeader, EventMeshRetCode.SUCCESS, null, - SendMessageBatchResponseBody.class); + SendMessageBatchResponseBody.class); return; } } 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 index e32bfd3cb2..c3602cc6fb 100644 --- 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 @@ -40,8 +40,8 @@ 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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; import org.apache.eventmesh.runtime.util.EventMeshUtil; import org.apache.eventmesh.runtime.util.RemotingHelper; @@ -60,11 +60,11 @@ public class BatchSendMessageV2Processor implements HttpRequestProcessor { - private final Logger cmdLogger = LoggerFactory.getLogger(EventMeshConstants.CMD); + private static final Logger CMD_LOGGER = LoggerFactory.getLogger(EventMeshConstants.CMD); - private final Logger aclLogger = LoggerFactory.getLogger(EventMeshConstants.ACL); - - private final Logger batchMessageLogger = LoggerFactory.getLogger("batchMessage"); + private static final Logger ACL_LOGGER = LoggerFactory.getLogger(EventMeshConstants.ACL); + + private static final Logger BATCH_MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.BATCH_MSG); private final EventMeshHTTPServer eventMeshHTTPServer; @@ -75,14 +75,13 @@ public BatchSendMessageV2Processor(EventMeshHTTPServer eventMeshHTTPServer) { this.acl = eventMeshHTTPServer.getAcl(); } - @Override public void processRequest(ChannelHandlerContext ctx, AsyncContext asyncContext) throws Exception { final HttpCommand request = asyncContext.getRequest(); final Integer requestCode = Integer.valueOf(request.getRequestCode()); - cmdLogger.info("cmd={}|{}|client2eventMesh|from={}|to={}", + CMD_LOGGER.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get(requestCode), EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), @@ -99,30 +98,29 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext EventMeshHTTPConfiguration httpConfiguration = eventMeshHTTPServer.getEventMeshHttpConfiguration(); SendMessageBatchV2ResponseHeader sendMessageBatchV2ResponseHeader = SendMessageBatchV2ResponseHeader.buildHeader( - requestCode, - httpConfiguration.getEventMeshCluster(), - httpConfiguration.getEventMeshEnv(), - httpConfiguration.getEventMeshIDC() - ); + requestCode, + httpConfiguration.getEventMeshCluster(), + httpConfiguration.getEventMeshEnv(), + httpConfiguration.getEventMeshIDC()); // todo: use validate processor to check - //validate event + // validate event if (!ObjectUtils.allNotNull(event.getSource(), event.getSpecVersion()) - || StringUtils.isAnyBlank(event.getId(), event.getType(), event.getSubject())) { + || StringUtils.isAnyBlank(event.getId(), event.getType(), event.getSubject())) { completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageBatchV2ResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageBatchV2ResponseBody.class); return; } - String idc = getExtension(event, ProtocolKey.ClientInstanceKey.IDC); - String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID); - String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS); + String idc = getExtension(event, ProtocolKey.ClientInstanceKey.IDC.getKey()); + String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID.getKey()); + String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS.getKey()); - //validate event-extension + // validate event-extension if (StringUtils.isAnyBlank(idc, pid, sys) || !StringUtils.isNumeric(pid)) { completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageBatchV2ResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageBatchV2ResponseBody.class); return; } @@ -133,32 +131,32 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext if (StringUtils.isAnyBlank(bizNo, topic, producerGroup) || event.getData() == null) { completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageBatchV2ResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageBatchV2ResponseBody.class); return; } String content = new String(Objects.requireNonNull(event.getData()).toBytes(), Constants.DEFAULT_CHARSET); if (content.length() > httpConfiguration.getEventMeshEventSize()) { - batchMessageLogger.error("Event size exceeds the limit: {}", httpConfiguration.getEventMeshEventSize()); + BATCH_MESSAGE_LOGGER.error("Event size exceeds the limit: {}", httpConfiguration.getEventMeshEventSize()); completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, - "Event size exceeds the limit: " + httpConfiguration.getEventMeshEventSize(), - SendMessageBatchV2ResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, + "Event size exceeds the limit: " + httpConfiguration.getEventMeshEventSize(), + SendMessageBatchV2ResponseBody.class); return; } - //do acl check + // do acl check if (httpConfiguration.isEventMeshServerSecurityEnable()) { String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - String user = getExtension(event, ProtocolKey.ClientInstanceKey.USERNAME); - String pass = getExtension(event, ProtocolKey.ClientInstanceKey.PASSWD); - String subsystem = getExtension(event, ProtocolKey.ClientInstanceKey.SYS); + String user = getExtension(event, ProtocolKey.ClientInstanceKey.USERNAME.getKey()); + String pass = getExtension(event, ProtocolKey.ClientInstanceKey.PASSWD.getKey()); + String subsystem = getExtension(event, ProtocolKey.ClientInstanceKey.SYS.getKey()); try { this.acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, topic, requestCode); } catch (Exception e) { completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, - EventMeshRetCode.EVENTMESH_ACL_ERR, e.getMessage(), SendMessageBatchV2ResponseBody.class); - aclLogger.warn("CLIENT HAS NO PERMISSION,BatchSendMessageV2Processor send failed", e); + EventMeshRetCode.EVENTMESH_ACL_ERR, e.getMessage(), SendMessageBatchV2ResponseBody.class); + ACL_LOGGER.warn("CLIENT HAS NO PERMISSION,BatchSendMessageV2Processor send failed", e); return; } } @@ -168,7 +166,7 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { summaryMetrics.recordSendBatchMsgDiscard(1); completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, - EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR, null, SendMessageBatchV2ResponseBody.class); + EventMeshRetCode.EVENTMESH_BATCH_SPEED_OVER_LIMIT_ERR, null, SendMessageBatchV2ResponseBody.class); return; } @@ -177,7 +175,7 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext batchEventMeshProducer.getMqProducerWrapper().getMeshMQProducer().setExtFields(); if (!batchEventMeshProducer.isStarted()) { completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, - EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR, null, SendMessageBatchV2ResponseBody.class); + EventMeshRetCode.EVENTMESH_BATCH_PRODUCER_STOPED_ERR, null, SendMessageBatchV2ResponseBody.class); return; } @@ -199,16 +197,15 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) .build(); - if (batchMessageLogger.isDebugEnabled()) { - batchMessageLogger.debug("msg2MQMsg suc, topic:{}, msg:{}", topic, event.getData()); - } + BATCH_MESSAGE_LOGGER.debug("msg2MQMsg suc, topic:{}, msg:{}", topic, event.getData()); } catch (Exception e) { - batchMessageLogger.error("msg2MQMsg err, topic:{}, msg:{}", topic, event.getData(), e); + BATCH_MESSAGE_LOGGER.error("msg2MQMsg err, topic:{}, msg:{}", topic, event.getData(), e); completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR, - EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() - + - EventMeshUtil.stackTrace(e, 2), SendMessageBatchV2ResponseBody.class); + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + + + EventMeshUtil.stackTrace(e, 2), + SendMessageBatchV2ResponseBody.class); return; } @@ -219,11 +216,12 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext try { batchEventMeshProducer.send(sendMessageContext, new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { long batchEndTime = System.currentTimeMillis(); summaryMetrics.recordBatchSendMsgCost(batchEndTime - batchStartTime); - batchMessageLogger.debug( + BATCH_MESSAGE_LOGGER.debug( "batchMessageV2|eventMesh2mq|REQ|ASYNC|bizSeqNo={}|send2MQCost={}ms|topic={}", bizNo, batchEndTime - batchStartTime, topic); } @@ -231,9 +229,9 @@ public void onSuccess(SendResult sendResult) { @Override public void onException(OnExceptionContext context) { long batchEndTime = System.currentTimeMillis(); - eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); summaryMetrics.recordBatchSendMsgCost(batchEndTime - batchStartTime); - batchMessageLogger.error( + BATCH_MESSAGE_LOGGER.error( "batchMessageV2|eventMesh2mq|REQ|ASYNC|bizSeqNo={}|send2MQCost={}ms|topic={}", bizNo, batchEndTime - batchStartTime, topic, context.getException()); } @@ -241,19 +239,19 @@ public void onException(OnExceptionContext context) { }); } catch (Exception e) { completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, EventMeshRetCode.EVENTMESH_SEND_BATCHLOG_MSG_ERR, - EventMeshRetCode.EVENTMESH_SEND_BATCHLOG_MSG_ERR.getErrMsg() - + - EventMeshUtil.stackTrace(e, 2), SendMessageBatchV2ResponseBody.class); + EventMeshRetCode.EVENTMESH_SEND_BATCHLOG_MSG_ERR.getErrMsg() + + + EventMeshUtil.stackTrace(e, 2), + SendMessageBatchV2ResponseBody.class); long batchEndTime = System.currentTimeMillis(); - eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); summaryMetrics.recordBatchSendMsgCost(batchEndTime - batchStartTime); - batchMessageLogger.error( + BATCH_MESSAGE_LOGGER.error( "batchMessageV2|eventMesh2mq|REQ|ASYNC|bizSeqNo={}|send2MQCost={}ms|topic={}", bizNo, batchEndTime - batchStartTime, topic, e); } completeResponse(request, asyncContext, sendMessageBatchV2ResponseHeader, - EventMeshRetCode.SUCCESS, null, SendMessageBatchV2ResponseBody.class); + EventMeshRetCode.SUCCESS, null, SendMessageBatchV2ResponseBody.class); } } - diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/CreateTopicProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/CreateTopicProcessor.java new file mode 100644 index 0000000000..3da0de9e0a --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/CreateTopicProcessor.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.HttpClientGroupMapping; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +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 io.netty.handler.codec.http.HttpResponseStatus; + +import com.fasterxml.jackson.core.type.TypeReference; + +@EventMeshTrace +public class CreateTopicProcessor implements AsyncHttpProcessor { + + private static final Logger HTTP_LOGGER = LoggerFactory.getLogger(EventMeshConstants.PROTOCOL_HTTP); + + private final transient EventMeshHTTPServer eventMeshHTTPServer; + + public CreateTopicProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest httpRequest) + throws Exception { + final AsyncContext asyncContext = handlerSpecific.getAsyncContext(); + final ChannelHandlerContext ctx = handlerSpecific.getCtx(); + final HttpEventWrapper requestWrapper = asyncContext.getRequest(); + + HttpEventWrapper responseWrapper; + + HTTP_LOGGER.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.getKey(), requestIp); + + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put(ProtocolKey.REQUEST_URI, requestWrapper.getRequestURI()); + responseHeaderMap + .put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshCluster()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, IPUtils.getLocalAddress()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEnv()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshIDC()); + + // validate body + byte[] requestBody = requestWrapper.getBody(); + + Map requestBodyMap = JsonUtils.parseTypeReferenceObject(new String(requestBody), + new TypeReference>() { + }); + + if (requestBodyMap.get("topic") == null || StringUtils.isBlank(requestBodyMap.get("topic").toString())) { + Map responseBodyMap = new HashMap<>(); + responseBodyMap.put("retCode", EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg() + "topic is null"); + HTTP_LOGGER.warn("create topic fail, topic is null"); + responseWrapper = requestWrapper.createHttpResponse(responseHeaderMap, responseBodyMap); + responseWrapper.setHttpResponseStatus(HttpResponseStatus.BAD_REQUEST); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + String topic = requestBodyMap.get("topic").toString(); + + long startTime = System.currentTimeMillis(); + try { + // pub topic in local cache + String[] topicArr = topic.split(";"); + for (String item : topicArr) { + item = StringUtils.deleteWhitespace(item); + if (!HttpClientGroupMapping.getInstance().getLocalTopicSet().contains(item)) { + HttpClientGroupMapping.getInstance().getLocalTopicSet().add(item); + HTTP_LOGGER.info("create topic success, topic:{}", item); + } + } + + final CompleteHandler handler = httpEventWrapper -> { + try { + HTTP_LOGGER.debug("{}", httpEventWrapper); + eventMeshHTTPServer.sendResponse(ctx, httpEventWrapper.httpResponse()); + eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordHTTPReqResTimeCost( + System.currentTimeMillis() - requestWrapper.getReqTime()); + } catch (Exception ex) { + // ignore + HTTP_LOGGER.warn("create topic, sendResponse fail,", ex); + } + }; + + responseWrapper = requestWrapper.createHttpResponse(EventMeshRetCode.SUCCESS); + asyncContext.onComplete(responseWrapper, handler); + + } catch (Exception e) { + Map responseBodyMap = new HashMap<>(); + responseBodyMap.put("retCode", EventMeshRetCode.EVENTMESH_RUNTIME_ERR.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.EVENTMESH_RUNTIME_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)); + responseWrapper = asyncContext.getRequest().createHttpResponse( + responseHeaderMap, responseBodyMap); + responseWrapper.setHttpResponseStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_RUNTIME_ERR, responseHeaderMap, + responseBodyMap, null); + long endTime = System.currentTimeMillis(); + HTTP_LOGGER.warn( + "create topic fail, eventMesh2client|cost={}ms|topic={}", endTime - startTime, topic, e); + eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordSendMsgCost(endTime - startTime); + } + } + + @Override + public String[] paths() { + return new String[] {RequestURI.CREATE_TOPIC.getRequestURI()}; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/DeleteTopicProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/DeleteTopicProcessor.java new file mode 100644 index 0000000000..0a4c2cc0f4 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/DeleteTopicProcessor.java @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.protocol.http.async.AsyncContext; +import org.apache.eventmesh.runtime.core.protocol.http.async.CompleteHandler; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.HttpClientGroupMapping; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +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 io.netty.handler.codec.http.HttpResponseStatus; + +import com.fasterxml.jackson.core.type.TypeReference; + +@EventMeshTrace +public class DeleteTopicProcessor implements AsyncHttpProcessor { + + private static final Logger HTTP_LOGGER = LoggerFactory.getLogger(EventMeshConstants.PROTOCOL_HTTP); + + private final transient EventMeshHTTPServer eventMeshHTTPServer; + + public DeleteTopicProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest httpRequest) + throws Exception { + final AsyncContext asyncContext = handlerSpecific.getAsyncContext(); + final ChannelHandlerContext ctx = handlerSpecific.getCtx(); + final HttpEventWrapper requestWrapper = asyncContext.getRequest(); + + HttpEventWrapper responseWrapper; + + HTTP_LOGGER.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.getKey(), requestIp); + + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put(ProtocolKey.REQUEST_URI, requestWrapper.getRequestURI()); + responseHeaderMap + .put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshCluster()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, IPUtils.getLocalAddress()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEnv()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshIDC()); + + // validate body + byte[] requestBody = requestWrapper.getBody(); + + Map requestBodyMap = JsonUtils.parseTypeReferenceObject(new String(requestBody), + new TypeReference>() { + }); + + if (requestBodyMap.get("topic") == null || StringUtils.isBlank(requestBodyMap.get("topic").toString())) { + Map responseBodyMap = new HashMap<>(); + responseBodyMap.put("retCode", EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR.getErrMsg() + "topic is null"); + HTTP_LOGGER.warn("delete topic fail, topic is null"); + responseWrapper = requestWrapper.createHttpResponse(responseHeaderMap, responseBodyMap); + responseWrapper.setHttpResponseStatus(HttpResponseStatus.BAD_REQUEST); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, + responseBodyMap, null); + return; + } + + String topic = requestBodyMap.get("topic").toString(); + + long startTime = System.currentTimeMillis(); + try { + // pub topic in local cache + String[] topicArr = topic.split(";"); + + // validate topic is exist in eventmesh + List faildTopic = new ArrayList<>(); + for (String deleteTopic : topicArr) { + if (!HttpClientGroupMapping.getInstance().getLocalTopicSet().contains(deleteTopic)) { + faildTopic.add(deleteTopic); + } + } + if (!faildTopic.isEmpty()) { + + Map responseBodyMap = new HashMap<>(); + StringBuilder sb = new StringBuilder(); + sb.append(faildTopic.toString()).append(" not exist in eventmesh"); + HTTP_LOGGER.warn("delete topic fail, {}", sb.toString()); + responseBodyMap.put("retCode", EventMeshRetCode.EVENTMESH_OPERATE_FAIL.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.EVENTMESH_OPERATE_FAIL.getErrMsg() + sb.toString()); + responseWrapper = requestWrapper.createHttpResponse(responseHeaderMap, responseBodyMap); + responseWrapper.setHttpResponseStatus(HttpResponseStatus.BAD_REQUEST); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_OPERATE_FAIL, responseHeaderMap, + responseBodyMap, null); + return; + } + for (String item : topicArr) { + boolean flag = HttpClientGroupMapping.getInstance().getLocalTopicSet().remove(StringUtils.deleteWhitespace(item)); + if (flag) { + HTTP_LOGGER.info("remove topic success, topic:{}", item); + } + } + + final CompleteHandler handler = httpEventWrapper -> { + try { + HTTP_LOGGER.debug("{}", httpEventWrapper); + eventMeshHTTPServer.sendResponse(ctx, httpEventWrapper.httpResponse()); + eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordHTTPReqResTimeCost( + System.currentTimeMillis() - requestWrapper.getReqTime()); + } catch (Exception ex) { + // ignore + HTTP_LOGGER.warn("delete topic, sendResponse fail,", ex); + } + }; + + responseWrapper = requestWrapper.createHttpResponse(EventMeshRetCode.SUCCESS); + asyncContext.onComplete(responseWrapper, handler); + + } catch (Exception e) { + Map responseBodyMap = new HashMap<>(); + responseBodyMap.put("retCode", EventMeshRetCode.EVENTMESH_RUNTIME_ERR.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.EVENTMESH_RUNTIME_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)); + responseWrapper = asyncContext.getRequest().createHttpResponse( + responseHeaderMap, responseBodyMap); + responseWrapper.setHttpResponseStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_RUNTIME_ERR, responseHeaderMap, + responseBodyMap, null); + long endTime = System.currentTimeMillis(); + HTTP_LOGGER.warn( + "delete topic fail, eventMesh2client|cost={}ms|topic={}", endTime - startTime, topic, e); + eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordSendMsgCost(endTime - startTime); + } + } + + @Override + public String[] paths() { + return new String[] {RequestURI.DELETE_TOPIC.getRequestURI()}; + } +} 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 index f4c92bb64c..7f877aab25 100644 --- 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 @@ -18,6 +18,7 @@ package org.apache.eventmesh.runtime.core.protocol.http.processor; import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.enums.ConnectionType; import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; import org.apache.eventmesh.common.utils.JsonUtils; @@ -69,7 +70,7 @@ @Slf4j public class HandlerService { - private final Logger httpLogger = LoggerFactory.getLogger(EventMeshConstants.PROTOCOL_HTTP); + private static final Logger HTTP_LOGGER = LoggerFactory.getLogger(EventMeshConstants.PROTOCOL_HTTP); private final Map httpProcessorMap = new ConcurrentHashMap<>(); @@ -81,7 +82,6 @@ public class HandlerService { public DefaultHttpDataFactory defaultHttpDataFactory = new DefaultHttpDataFactory(false); - public void init() { log.info("HandlerService start "); } @@ -148,14 +148,17 @@ public void handler(ChannelHandlerContext ctx, HttpRequest httpRequest, ThreadPo } private void sendResponse(ChannelHandlerContext ctx, HttpRequest request, HttpResponse response) { - this.sendResponse(ctx, request, response, true); + this.sendPersistentResponse(ctx, request, response, true); } - private void sendResponse(ChannelHandlerContext ctx, HttpRequest httpRequest, HttpResponse response, boolean isClose) { + /** + * persistent connection + */ + private void sendPersistentResponse(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", + HTTP_LOGGER.warn("send response to [{}] fail, will close this channel", RemotingHelper.parseChannelRemoteAddr(f.channel())); if (isClose) { f.channel().close(); @@ -164,19 +167,32 @@ private void sendResponse(ChannelHandlerContext ctx, HttpRequest httpRequest, Ht }); } + /** + * short-lived connection + */ + private void sendShortResponse(ChannelHandlerContext ctx, HttpRequest httpRequest, HttpResponse response) { + ReferenceCountUtil.release(httpRequest); + ctx.writeAndFlush(response).addListener((ChannelFutureListener) f -> { + if (!f.isSuccess()) { + HTTP_LOGGER.warn("send response to [{}] with short-lived connection fail, will close this channel", + RemotingHelper.parseChannelRemoteAddr(f.channel())); + } + }).addListener(ChannelFutureListener.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 + // 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 + // parse http body FullHttpRequest fullHttpRequest = (FullHttpRequest) httpRequest; final Map bodyMap = new HashMap<>(); if (HttpMethod.GET == fullHttpRequest.method()) { @@ -193,8 +209,7 @@ private HttpEventWrapper parseHttpRequest(HttpRequest httpRequest) throws IOExce .ofNullable(JsonUtils.parseTypeReferenceObject( new String(body, Constants.DEFAULT_CHARSET), new TypeReference>() { - } - )) + })) .ifPresent(bodyMap::putAll); } } else { @@ -246,7 +261,6 @@ class HandlerSpecific implements Runnable { private CloudEvent ce; - public void run() { String processorKey = "/"; for (String eventProcessorKey : httpProcessorMap.keySet()) { @@ -267,7 +281,11 @@ public void run() { } response = processorWrapper.httpProcessor.handler(request); - this.postHandler(); + if (processorWrapper.httpProcessor instanceof ShortHttpProcessor) { + this.postHandler(ConnectionType.SHORT_LIVED); + return; + } + this.postHandler(ConnectionType.PERSISTENT); } catch (Throwable e) { exception = e; // todo: according exception to generate response @@ -276,23 +294,23 @@ public void run() { } } - private void postHandler() { + private void postHandler(ConnectionType type) { metrics.getSummaryMetrics().recordHTTPRequest(); - if (httpLogger.isDebugEnabled()) { - httpLogger.debug("{}", request); - } + HTTP_LOGGER.debug("{}", request); if (Objects.isNull(response)) { this.response = HttpResponseUtils.createSuccess(); } this.traceOperation.endTrace(ce); - HandlerService.this.sendResponse(ctx, this.request, this.response); + if (type == ConnectionType.PERSISTENT) { + HandlerService.this.sendResponse(ctx, this.request, this.response); + } else if (type == ConnectionType.SHORT_LIVED) { + sendShortResponse(ctx, this.request, this.response); + } } private void preHandler() { metrics.getSummaryMetrics().recordHTTPReqResTimeCost(System.currentTimeMillis() - requestTime); - if (httpLogger.isDebugEnabled()) { - httpLogger.debug("{}", response); - } + HTTP_LOGGER.debug("{}", response); } private void error() { @@ -303,7 +321,6 @@ private void error() { HandlerService.this.sendResponse(ctx, this.request, this.response); } - public void setResponseJsonBody(String body) { this.sendResponse(HttpResponseUtils.setResponseJsonBody(body, ctx)); } @@ -314,7 +331,7 @@ public void setResponseTextBody(String body) { public void sendResponse(HttpResponse response) { this.response = response; - this.postHandler(); + this.postHandler(ConnectionType.PERSISTENT); } public void sendResponse(Map responseHeaderMap, Map responseBodyMap) { @@ -322,7 +339,7 @@ public void sendResponse(Map responseHeaderMap, Map> tmpMap = new ConcurrentHashMap<>(); @@ -112,15 +107,15 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext> clientInfoMap = - eventMeshHTTPServer.getSubscriptionManager().getLocalClientInfoMapping(); + eventMeshHTTPServer.getSubscriptionManager().getLocalClientInfoMapping(); synchronized (clientInfoMap) { for (final Map.Entry> groupTopicClientMapping : tmpMap.entrySet()) { final List localClientList = clientInfoMap.get(groupTopicClientMapping.getKey()); @@ -168,27 +161,23 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext handler = httpCommand -> { try { - if (log.isDebugEnabled()) { - log.debug("{}", httpCommand); - } + log.debug("{}", httpCommand); eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); summaryMetrics.recordHTTPReqResTimeCost( System.currentTimeMillis() - request.getReqTime()); } catch (Exception ex) { - //ignore + // ignore } }; responseEventMeshCommand = request.createHttpCommandResponse(EventMeshRetCode.SUCCESS); asyncContext.onComplete(responseEventMeshCommand, handler); } catch (Exception e) { completeResponse(request, asyncContext, heartbeatResponseHeader, - EventMeshRetCode.EVENTMESH_HEARTBEAT_ERR, - EventMeshRetCode.EVENTMESH_HEARTBEAT_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2), - HeartbeatResponseBody.class); + EventMeshRetCode.EVENTMESH_HEARTBEAT_ERR, + EventMeshRetCode.EVENTMESH_HEARTBEAT_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2), + HeartbeatResponseBody.class); final long elapsedTime = System.currentTimeMillis() - startTime; - if (log.isErrorEnabled()) { - log.error("message|eventMesh2mq|REQ|ASYNC|heartBeatMessageCost={}ms", elapsedTime, e); - } + log.error("message|eventMesh2mq|REQ|ASYNC|heartBeatMessageCost={}ms", elapsedTime, e); summaryMetrics.recordSendMsgFailed(); summaryMetrics.recordSendMsgCost(elapsedTime); } 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 index b6e5f7f445..b5863e5ddd 100644 --- 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 @@ -48,7 +48,6 @@ import lombok.extern.slf4j.Slf4j; - @EventMeshTrace @Slf4j public class LocalSubscribeEventProcessor extends AbstractEventProcessor { @@ -68,13 +67,11 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final HttpEventWrapper requestWrapper = handlerSpecific.getAsyncContext().getRequest(); String localAddress = IPUtils.getLocalAddress(); String remoteAddr = RemotingHelper.parseChannelRemoteAddr(channel); - if (log.isInfoEnabled()) { - log.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), - EventMeshConstants.PROTOCOL_HTTP, remoteAddr, localAddress); - } + log.info("uri={}|{}|client2eventMesh|from={}|to={}", + requestWrapper.getRequestURI(), EventMeshConstants.PROTOCOL_HTTP, remoteAddr, localAddress); // user request header - requestWrapper.getHeaderMap().put(ProtocolKey.ClientInstanceKey.IP, remoteAddr); + requestWrapper.getHeaderMap().put(ProtocolKey.ClientInstanceKey.IP.getKey(), remoteAddr); // build sys header requestWrapper.buildSysHeaderForClient(); @@ -82,19 +79,18 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final Map sysHeaderMap = requestWrapper.getSysHeaderMap(); final Map responseBodyMap = new HashMap<>(); - //validate header + // validate header if (validateSysHeader(sysHeaderMap)) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, responseBodyMap, null); return; } - //validate body + // validate body final Map requestBodyMap = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( new String(requestWrapper.getBody(), Constants.DEFAULT_CHARSET), new TypeReference>() { - } - )).orElseGet(HashMap::new); + })).orElseGet(HashMap::new); if (validatedRequestBodyMap(requestBodyMap)) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, @@ -110,22 +106,19 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final List subscriptionList = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( topic, new TypeReference>() { - } - )).orElseGet(Collections::emptyList); + })).orElseGet(Collections::emptyList); - //do acl check + // do acl check if (eventMeshHTTPServer.getEventMeshHttpConfiguration().isEventMeshServerSecurityEnable()) { for (final SubscriptionItem item : subscriptionList) { try { - String user = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.USERNAME).toString(); - String pass = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PASSWD).toString(); - String subsystem = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString(); + String user = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.USERNAME.getKey()).toString(); + String pass = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PASSWD.getKey()).toString(); + String subsystem = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS.getKey()).toString(); this.acl.doAclCheckInHttpReceive(remoteAddr, user, pass, subsystem, item.getTopic(), requestWrapper.getRequestURI()); } catch (Exception e) { - if (log.isWarnEnabled()) { - log.warn("CLIENT HAS NO PERMISSION,SubscribeProcessor subscribe failed", e); - } + log.warn("CLIENT HAS NO PERMISSION,SubscribeProcessor subscribe failed", e); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_ACL_ERR, responseHeaderMap, responseBodyMap, null); @@ -138,18 +131,14 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final try { if (!IPUtils.isValidDomainOrIp(url, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshIpv4BlackList(), eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshIpv6BlackList())) { - if (log.isErrorEnabled()) { - log.error("subscriber url {} is not valid", url); - } + log.error("subscriber url {} is not valid", url); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, responseBodyMap, null); return; } } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("subscriber url {} is not valid", url, e); - } + log.error("subscriber url {} is not valid", url, e); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, responseBodyMap, null); @@ -159,9 +148,7 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final // obtain webhook delivery agreement for Abuse Protection if (!WebhookUtil.obtainDeliveryAgreement(eventMeshHTTPServer.getHttpClientPool().getClient(), url, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshWebhookOrigin())) { - if (log.isErrorEnabled()) { - log.error("subscriber url {} is not allowed by the target system", url); - } + log.error("subscriber url {} is not allowed by the target system", url); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, responseBodyMap, null); return; @@ -184,19 +171,14 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|url={}", - System.currentTimeMillis() - startTime, - JsonUtils.toJSONString(subscriptionList), - url, e); - } + log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|url={}", + System.currentTimeMillis() - startTime, JsonUtils.toJSONString(subscriptionList), url, e); - handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SUBSCRIBE_ERR, responseHeaderMap, - responseBodyMap, null); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SUBSCRIBE_ERR, responseHeaderMap, responseBodyMap, null); } // Update service metadata - updateMetadata(); + eventMeshHTTPServer.getSubscriptionManager().updateMetaData(); } } @@ -209,11 +191,11 @@ public String[] paths() { private ClientInfo getClientInfo(final HttpEventWrapper requestWrapper) { final Map requestHeaderMap = requestWrapper.getSysHeaderMap(); ClientInfo clientInfo = new ClientInfo(); - clientInfo.setEnv(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.ENV).toString()); - clientInfo.setIdc(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString()); - clientInfo.setSys(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString()); - clientInfo.setIp(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IP).toString()); - clientInfo.setPid(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()); + clientInfo.setEnv(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.ENV.getKey()).toString()); + clientInfo.setIdc(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC.getKey()).toString()); + clientInfo.setSys(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS.getKey()).toString()); + clientInfo.setIp(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IP.getKey()).toString()); + clientInfo.setPid(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.PID.getKey()).toString()); return clientInfo; } } 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 index 42512167d3..bb9c61ed7a 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.runtime.core.protocol.http.processor; - import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; import org.apache.eventmesh.common.protocol.http.common.EventMeshRetCode; @@ -77,13 +76,12 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final String localAddress = IPUtils.getLocalAddress(); String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - if (log.isInfoEnabled()) { - log.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), - EventMeshConstants.PROTOCOL_HTTP, remoteAddr, localAddress); - } + + log.info("uri={}|{}|client2eventMesh|from={}|to={}", + requestWrapper.getRequestURI(), EventMeshConstants.PROTOCOL_HTTP, remoteAddr, localAddress); // user request header - requestWrapper.getHeaderMap().put(ProtocolKey.ClientInstanceKey.IP, remoteAddr); + requestWrapper.getHeaderMap().put(ProtocolKey.ClientInstanceKey.IP.getKey(), remoteAddr); // build sys header requestWrapper.buildSysHeaderForClient(); @@ -92,21 +90,20 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final Map sysHeaderMap = requestWrapper.getSysHeaderMap(); final Map responseBodyMap = new HashMap<>(); - //validate header + // validate header if (validateSysHeader(sysHeaderMap)) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, responseBodyMap, null); return; } - //validate body + // validate body final byte[] requestBody = requestWrapper.getBody(); final Map requestBodyMap = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( new String(requestBody, Constants.DEFAULT_CHARSET), new TypeReference>() { - } - )).orElseGet(Maps::newHashMap); + })).orElseGet(Maps::newHashMap); if (validatedRequestBodyMap(requestBodyMap)) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, @@ -121,10 +118,9 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final List unSubTopicList = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( JsonUtils.toJSONString(requestBodyMap.get(EventMeshConstants.MANAGE_TOPIC)), new TypeReference>() { - } - )).orElseGet(Collections::emptyList); + })).orElseGet(Collections::emptyList); - final String pid = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString(); + final String pid = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID.getKey()).toString(); synchronized (eventMeshHTTPServer.getSubscriptionManager().getLocalClientInfoMapping()) { boolean isChange = true; @@ -139,15 +135,13 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final Client client = clientIterator.next(); if (StringUtils.equals(client.getPid(), pid) && StringUtils.equals(client.getUrl(), unSubscribeUrl)) { - if (log.isWarnEnabled()) { - log.warn("client {} start unsubscribe", JsonUtils.toJSONString(client)); - } + log.warn("client {} start unsubscribe", JsonUtils.toJSONString(client)); clientIterator.remove(); } } if (CollectionUtils.isNotEmpty(groupTopicClients)) { - //change url + // change url final Map> idcUrls = new HashMap<>(); final Set clientUrls = new HashSet<>(); for (final Client client : groupTopicClients) { @@ -197,16 +191,13 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" - + "|topic={}|url={}", System.currentTimeMillis() - startTime, - JsonUtils.toJSONString(unSubTopicList), unSubscribeUrl, e); - } + log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" + + "|topic={}|url={}", System.currentTimeMillis() - startTime, JsonUtils.toJSONString(unSubTopicList), unSubscribeUrl, e); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR, responseHeaderMap, responseBodyMap, null); } } else { - //remove + // remove try { eventMeshHTTPServer.getConsumerManager() .notifyConsumerManager(consumerGroup, null); @@ -221,18 +212,15 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final eventMeshHTTPServer.getSubscriptionManager().getLocalConsumerGroupMapping().keySet() .removeIf(s -> StringUtils.equals(consumerGroup, s)); } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" - + "|topic={}|url={}", System.currentTimeMillis() - startTime, - JsonUtils.toJSONString(unSubTopicList), unSubscribeUrl, e); - } + log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" + + "|topic={}|url={}", System.currentTimeMillis() - startTime, JsonUtils.toJSONString(unSubTopicList), unSubscribeUrl, e); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR, responseHeaderMap, responseBodyMap, null); } } // Update service metadata - updateMetadata(); + eventMeshHTTPServer.getSubscriptionManager().updateMetaData(); } } @@ -241,10 +229,7 @@ public String[] paths() { return new String[]{RequestURI.UNSUBSCRIBE_LOCAL.getRequestURI()}; } - - private void registerClient(final HttpEventWrapper requestWrapper, - final String consumerGroup, - final List topicList, final String url) { + private void registerClient(final HttpEventWrapper requestWrapper, final String consumerGroup, final List topicList, final String url) { Objects.requireNonNull(requestWrapper, "requestWrapper can not be null"); Objects.requireNonNull(consumerGroup, "consumerGroup can not be null"); Objects.requireNonNull(topicList, "topicList can not be null"); @@ -253,11 +238,11 @@ private void registerClient(final HttpEventWrapper requestWrapper, final Map requestHeaderMap = requestWrapper.getSysHeaderMap(); for (final String topic : topicList) { final Client client = new Client(); - client.setEnv(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.ENV).toString()); - client.setIdc(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString()); - client.setSys(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString()); - client.setIp(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IP).toString()); - client.setPid(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()); + client.setEnv(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.ENV.getKey()).toString()); + client.setIdc(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC.getKey()).toString()); + client.setSys(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS.getKey()).toString()); + client.setIp(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.IP.getKey()).toString()); + client.setPid(requestHeaderMap.get(ProtocolKey.ClientInstanceKey.PID.getKey()).toString()); client.setConsumerGroup(consumerGroup); client.setTopic(topic); client.setUrl(url); diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/QuerySubscriptionProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/QuerySubscriptionProcessor.java new file mode 100644 index 0000000000..6ffee13a6c --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/processor/QuerySubscriptionProcessor.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.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.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.async.CompleteHandler; +import org.apache.eventmesh.runtime.core.protocol.http.consumer.HttpClientGroupMapping; +import org.apache.eventmesh.runtime.util.EventMeshUtil; +import org.apache.eventmesh.runtime.util.RemotingHelper; + +import java.util.HashMap; +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 io.netty.handler.codec.http.HttpResponseStatus; + +@EventMeshTrace +public class QuerySubscriptionProcessor implements AsyncHttpProcessor { + + private static final Logger HTTP_LOGGER = LoggerFactory.getLogger(EventMeshConstants.PROTOCOL_HTTP); + + private final transient EventMeshHTTPServer eventMeshHTTPServer; + + public QuerySubscriptionProcessor(EventMeshHTTPServer eventMeshHTTPServer) { + this.eventMeshHTTPServer = eventMeshHTTPServer; + } + + @Override + public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest httpRequest) + throws Exception { + final AsyncContext asyncContext = handlerSpecific.getAsyncContext(); + final ChannelHandlerContext ctx = handlerSpecific.getCtx(); + final HttpEventWrapper requestWrapper = asyncContext.getRequest(); + + HttpEventWrapper responseWrapper; + + HTTP_LOGGER.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), + EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), IPUtils.getLocalAddress()); + + Map responseHeaderMap = new HashMap<>(); + responseHeaderMap.put(ProtocolKey.REQUEST_URI, requestWrapper.getRequestURI()); + responseHeaderMap + .put(ProtocolKey.EventMeshInstanceKey.EVENTMESHCLUSTER, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshCluster()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIP, IPUtils.getLocalAddress()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHENV, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEnv()); + responseHeaderMap.put(ProtocolKey.EventMeshInstanceKey.EVENTMESHIDC, eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshIDC()); + + long startTime = System.currentTimeMillis(); + try { + // pub topic in local cache + + final CompleteHandler handler = httpEventWrapper -> { + try { + HTTP_LOGGER.debug("{}", httpEventWrapper); + eventMeshHTTPServer.sendResponse(ctx, httpEventWrapper.httpResponse()); + eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordHTTPReqResTimeCost( + System.currentTimeMillis() - requestWrapper.getReqTime()); + } catch (Exception ex) { + HTTP_LOGGER.warn("query subscription, sendResponse fail", ex); + } + }; + + Map responseBodyMap = new HashMap<>(); + + responseBodyMap.put("subsrciption", HttpClientGroupMapping.getInstance().querySubscription()); + responseBodyMap.put("localTopicSet", HttpClientGroupMapping.getInstance().getLocalTopicSet()); + + responseWrapper = requestWrapper.createHttpResponse(responseHeaderMap, responseBodyMap); + asyncContext.onComplete(responseWrapper, handler); + } catch (Exception e) { + Map responseBodyMap = new HashMap<>(); + responseBodyMap.put("retCode", EventMeshRetCode.EVENTMESH_RUNTIME_ERR.getRetCode()); + responseBodyMap.put("retMsg", EventMeshRetCode.EVENTMESH_RUNTIME_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2)); + responseWrapper = asyncContext.getRequest().createHttpResponse( + responseHeaderMap, responseBodyMap); + responseWrapper.setHttpResponseStatus(HttpResponseStatus.INTERNAL_SERVER_ERROR); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_RUNTIME_ERR, responseHeaderMap, + responseBodyMap, null); + long endTime = System.currentTimeMillis(); + HTTP_LOGGER.warn("query subscription fail,eventMesh2client|cost={}ms", endTime - startTime, e); + eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordSendMsgFailed(); + eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordSendMsgCost(endTime - startTime); + } + } + + @Override + public String[] paths() { + return new String[] {RequestURI.SUBSCRIPTION_QUERY.getRequestURI()}; + } +} 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 index dc2a9bed8a..43f90ea661 100644 --- 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 @@ -33,7 +33,6 @@ 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.lang3.StringUtils; import org.apache.http.impl.client.CloseableHttpClient; @@ -79,12 +78,11 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest String localAddress = IPUtils.getLocalAddress(); String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); httpLogger.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), - EventMeshConstants.PROTOCOL_HTTP, remoteAddr, localAddress - ); + EventMeshConstants.PROTOCOL_HTTP, remoteAddr, localAddress); // user request header Map userRequestHeaderMap = requestWrapper.getHeaderMap(); - userRequestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, remoteAddr); + userRequestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP.getKey(), remoteAddr); // build sys header requestWrapper.buildSysHeaderForClient(); @@ -95,21 +93,20 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest Map responseBodyMap = new HashMap<>(); - //validate header + // validate header if (validateSysHeader(sysHeaderMap)) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, responseBodyMap, null); return; } - //validate body + // validate body byte[] requestBody = requestWrapper.getBody(); Map requestBodyMap = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( new String(requestBody, Constants.DEFAULT_CHARSET), new TypeReference>() { - } - )).orElseGet(Maps::newHashMap); + })).orElseGet(Maps::newHashMap); if (validatedRequestBodyMap(requestBodyMap)) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, @@ -117,23 +114,21 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest return; } - String url = requestBodyMap.get(EventMeshConstants.URL).toString(); - String consumerGroup = requestBodyMap.get(EventMeshConstants.CONSUMER_GROUP).toString(); + // String url = requestBodyMap.get(EventMeshConstants.URL).toString(); String topic = JsonUtils.toJSONString(requestBodyMap.get(EventMeshConstants.MANAGE_TOPIC)); // SubscriptionItem List subscriptionList = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( topic, new TypeReference>() { - } - )).orElseGet(Collections::emptyList); + })).orElseGet(Collections::emptyList); - //do acl check + // do acl check EventMeshHTTPConfiguration eventMeshHttpConfiguration = eventMeshHTTPServer.getEventMeshHttpConfiguration(); if (eventMeshHttpConfiguration.isEventMeshServerSecurityEnable()) { - String user = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.USERNAME).toString(); - String pass = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PASSWD).toString(); - String subsystem = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString(); + String user = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.USERNAME.getKey()).toString(); + String pass = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PASSWD.getKey()).toString(); + String subsystem = sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS.getKey()).toString(); for (SubscriptionItem item : subscriptionList) { try { this.acl.doAclCheckInHttpReceive(remoteAddr, user, pass, subsystem, item.getTopic(), requestWrapper.getRequestURI()); @@ -146,32 +141,32 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest } // validate URL - try { - if (!IPUtils.isValidDomainOrIp(url, eventMeshHttpConfiguration.getEventMeshIpv4BlackList(), - eventMeshHttpConfiguration.getEventMeshIpv6BlackList())) { - 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; - } - - CloseableHttpClient closeableHttpClient = eventMeshHTTPServer.getHttpClientPool().getClient(); - // obtain webhook delivery agreement for Abuse Protection - boolean isWebhookAllowed = WebhookUtil.obtainDeliveryAgreement(closeableHttpClient, - url, eventMeshHttpConfiguration.getEventMeshWebhookOrigin()); - - 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; - } + // try { + // if (!IPUtils.isValidDomainOrIp(url, eventMeshHttpConfiguration.getEventMeshIpv4BlackList(), + // eventMeshHttpConfiguration.getEventMeshIpv6BlackList())) { + // 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; + // } + // + // CloseableHttpClient closeableHttpClient = eventMeshHTTPServer.getHttpClientPool().getClient(); + // // obtain webhook delivery agreement for Abuse Protection + // boolean isWebhookAllowed = WebhookUtil.obtainDeliveryAgreement(closeableHttpClient, + // url, eventMeshHttpConfiguration.getEventMeshWebhookOrigin()); + // + // 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 { @@ -187,19 +182,19 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest String targetMesh = requestBodyMap.get("remoteMesh") == null ? "" : requestBodyMap.get("remoteMesh").toString(); // Get mesh address from registry - String meshAddress = getTargetMesh(consumerGroup, subscriptionList); + String meshAddress = getTargetMesh(eventMeshHttpConfiguration.getMeshGroup(), subscriptionList); if (StringUtils.isNotBlank(meshAddress)) { targetMesh = meshAddress; } + CloseableHttpClient closeableHttpClient = eventMeshHTTPServer.getHttpClientPool().getClient(); String remoteResult = post(closeableHttpClient, targetMesh, builderRemoteHeaderMap(localAddress), remoteBodyMap, response -> EntityUtils.toString(response.getEntity(), Constants.DEFAULT_CHARSET)); Map remoteResultMap = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( remoteResult, new TypeReference>() { - } - )).orElseGet(Maps::newHashMap); + })).orElseGet(Maps::newHashMap); if (String.valueOf(EventMeshRetCode.SUCCESS.getRetCode()).equals(remoteResultMap.get(EventMeshConstants.RET_CODE))) { responseBodyMap.put(EventMeshConstants.RET_CODE, EventMeshRetCode.SUCCESS.getRetCode()); @@ -213,10 +208,8 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest } catch (Exception e) { long endTime = System.currentTimeMillis(); - httpLogger.error( - "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}" - + "|bizSeqNo={}|uniqueId={}", endTime - startTime, - JsonUtils.toJSONString(subscriptionList), url, e); + httpLogger.error("subscribe Remote|cost={}ms|topic={}", endTime - startTime, + JsonUtils.toJSONString(subscriptionList), e); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SUBSCRIBE_ERR, responseHeaderMap, responseBodyMap, null); } 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 index 31dbb19121..edbd9ccfa9 100644 --- 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 @@ -77,12 +77,11 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest String localAddress = IPUtils.getLocalAddress(); String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); httpLogger.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), - EventMeshConstants.PROTOCOL_HTTP, remoteAddr, localAddress - ); + EventMeshConstants.PROTOCOL_HTTP, remoteAddr, localAddress); // user request header Map userRequestHeaderMap = requestWrapper.getHeaderMap(); - userRequestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, remoteAddr); + userRequestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP.getKey(), remoteAddr); // build sys header requestWrapper.buildSysHeaderForClient(); @@ -93,21 +92,20 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest Map responseBodyMap = new HashMap<>(); - //validate header + // validate header if (validateSysHeader(sysHeaderMap)) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, responseHeaderMap, responseBodyMap, null); return; } - //validate body + // validate body byte[] requestBody = requestWrapper.getBody(); Map requestBodyMap = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( new String(requestBody, Constants.DEFAULT_CHARSET), new TypeReference>() { - } - )).orElseGet(Maps::newHashMap); + })).orElseGet(Maps::newHashMap); if (validatedRequestBodyMap(requestBodyMap)) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, @@ -115,9 +113,7 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest return; } - String unSubscribeUrl = requestBodyMap.get(EventMeshConstants.URL).toString(); - String consumerGroup = requestBodyMap.get(EventMeshConstants.CONSUMER_GROUP).toString(); - String topic = requestBodyMap.get(EventMeshConstants.MANAGE_TOPIC).toString(); + String topic = JsonUtils.toJSONString(requestBodyMap.get(EventMeshConstants.MANAGE_TOPIC).toString()); long startTime = System.currentTimeMillis(); try { @@ -142,8 +138,7 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest List unSubTopicList = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( JsonUtils.toJSONString(requestBodyMap.get(EventMeshConstants.MANAGE_TOPIC)), new TypeReference>() { - } - )).orElseGet(Collections::emptyList); + })).orElseGet(Collections::emptyList); String targetMesh = ""; if (!Objects.isNull(requestBodyMap.get("remoteMesh"))) { @@ -156,7 +151,7 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest return subscriptionItem; }).collect(Collectors.toList()); // Get mesh address from registry - String meshAddress = getTargetMesh(consumerGroup, subscriptionList); + String meshAddress = getTargetMesh(meshGroup, subscriptionList); if (StringUtils.isNotBlank(meshAddress)) { targetMesh = meshAddress; } @@ -169,8 +164,7 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest Map remoteResultMap = Optional.ofNullable(JsonUtils.parseTypeReferenceObject( remoteResult, new TypeReference>() { - } - )).orElseGet(Maps::newHashMap); + })).orElseGet(Maps::newHashMap); if (String.valueOf(EventMeshRetCode.SUCCESS.getRetCode()).equals(remoteResultMap.get(EventMeshConstants.RET_CODE))) { responseBodyMap.put(EventMeshConstants.RET_CODE, EventMeshRetCode.SUCCESS.getRetCode()); @@ -182,10 +176,7 @@ public void handler(HandlerService.HandlerSpecific handlerSpecific, HttpRequest } } catch (Exception e) { long endTime = System.currentTimeMillis(); - httpLogger.error( - "message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}" - + "|bizSeqNo={}|uniqueId={}", endTime - startTime, - topic, unSubscribeUrl, e); + httpLogger.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}", endTime - startTime, topic, e); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR, responseHeaderMap, responseBodyMap, null); } @@ -196,5 +187,4 @@ public String[] paths() { return new String[]{RequestURI.UNSUBSCRIBE_REMOTE.getRequestURI()}; } - } 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 index d5a408394f..d23a26d8ce 100644 --- 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 @@ -40,8 +40,8 @@ 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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; import org.apache.eventmesh.runtime.util.EventMeshUtil; import org.apache.eventmesh.runtime.util.RemotingHelper; @@ -59,7 +59,7 @@ public class ReplyMessageProcessor implements HttpRequestProcessor { - public final Logger messageLogger = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); + public static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); public final Logger cmdLogger = LoggerFactory.getLogger(EventMeshConstants.CMD); @@ -88,27 +88,27 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext EventMeshHTTPConfiguration httpConfiguration = eventMeshHTTPServer.getEventMeshHttpConfiguration(); ReplyMessageResponseHeader replyMessageResponseHeader = ReplyMessageResponseHeader.buildHeader(Integer.valueOf(request.getRequestCode()), - httpConfiguration.getEventMeshCluster(), - localAddress, httpConfiguration.getEventMeshEnv(), - httpConfiguration.getEventMeshIDC()); + httpConfiguration.getEventMeshCluster(), + localAddress, httpConfiguration.getEventMeshEnv(), + httpConfiguration.getEventMeshIDC()); - //validate event + // validate event if (!ObjectUtils.allNotNull(event, event.getSource(), event.getSpecVersion()) || StringUtils.isAnyBlank(event.getId(), event.getType(), event.getSubject())) { completeResponse(request, asyncContext, replyMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, ReplyMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, ReplyMessageResponseBody.class); return; } - String idc = getExtension(event, ProtocolKey.ClientInstanceKey.IDC); - String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID); - String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS); + String idc = getExtension(event, ProtocolKey.ClientInstanceKey.IDC.getKey()); + String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID.getKey()); + String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS.getKey()); - //validate HEADER + // validate HEADER if (StringUtils.isAnyBlank(idc, pid, sys) || !StringUtils.isNumeric(pid)) { completeResponse(request, asyncContext, replyMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, ReplyMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, ReplyMessageResponseBody.class); return; } @@ -116,11 +116,11 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext String uniqueId = getExtension(event, SendMessageRequestBody.UNIQUEID); String producerGroup = getExtension(event, SendMessageRequestBody.PRODUCERGROUP); - //validate body + // validate body if (StringUtils.isAnyBlank(bizNo, uniqueId, producerGroup) || event.getData() == null) { completeResponse(request, asyncContext, replyMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, ReplyMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, ReplyMessageResponseBody.class); return; } @@ -130,18 +130,18 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { summaryMetrics.recordHTTPDiscard(); completeResponse(request, asyncContext, replyMessageResponseHeader, - EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR, null, ReplyMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR, null, ReplyMessageResponseBody.class); return; } String content = event.getData() == null ? "" : new String(event.getData().toBytes(), Constants.DEFAULT_CHARSET); if (content.length() > httpConfiguration.getEventMeshEventSize()) { httpLogger.error("Event size exceeds the limit: {}", - httpConfiguration.getEventMeshEventSize()); + httpConfiguration.getEventMeshEventSize()); completeResponse(request, asyncContext, replyMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, - "Event size exceeds the limit: " + httpConfiguration.getEventMeshEventSize(), - ReplyMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, + "Event size exceeds the limit: " + httpConfiguration.getEventMeshEventSize(), + ReplyMessageResponseBody.class); return; } @@ -149,7 +149,7 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext if (!eventMeshProducer.isStarted()) { completeResponse(request, asyncContext, replyMessageResponseHeader, - EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR, null, ReplyMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR, null, ReplyMessageResponseBody.class); return; } @@ -161,13 +161,13 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext replyTopic = replyMQCluster + "-" + replyTopic; } else { completeResponse(request, asyncContext, replyMessageResponseHeader, - EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR, null, ReplyMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR, null, ReplyMessageResponseBody.class); return; } try { // body - //omsMsg.setBody(replyMessageRequestBody.getContent().getBytes(EventMeshConstants.DEFAULT_CHARSET)); + // omsMsg.setBody(replyMessageRequestBody.getContent().getBytes(EventMeshConstants.DEFAULT_CHARSET)); event = CloudEventBuilder.from(event) .withSubject(replyTopic) .withExtension(EventMeshConstants.MSG_TYPE, EventMeshConstants.PERSISTENT) @@ -175,17 +175,14 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext .withExtension(EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) .build(); - if (messageLogger.isDebugEnabled()) { - messageLogger.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, replyTopic); - } + MESSAGE_LOGGER.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, replyTopic); } catch (Exception e) { - messageLogger.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, replyTopic, e); + MESSAGE_LOGGER.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, replyTopic, e); completeResponse(request, asyncContext, replyMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR, - EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2), - ReplyMessageResponseBody.class - ); + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR, + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2), + ReplyMessageResponseBody.class); return; } @@ -193,14 +190,12 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext summaryMetrics.recordReplyMsg(); CompleteHandler handler = httpCommand -> { try { - if (httpLogger.isDebugEnabled()) { - httpLogger.debug("{}", httpCommand); - } + httpLogger.debug("{}", httpCommand); eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); summaryMetrics.recordHTTPReqResTimeCost( System.currentTimeMillis() - request.getReqTime()); } catch (Exception ex) { - //ignore + // ignore } }; @@ -210,15 +205,16 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext .build(); sendMessageContext.setEvent(clone); eventMeshProducer.reply(sendMessageContext, new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { HttpCommand succ = request.createHttpCommandResponse( - replyMessageResponseHeader, - ReplyMessageResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), EventMeshRetCode.SUCCESS.getErrMsg())); + replyMessageResponseHeader, + ReplyMessageResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), EventMeshRetCode.SUCCESS.getErrMsg())); asyncContext.onComplete(succ, handler); long endTime = System.currentTimeMillis(); summaryMetrics.recordReplyMsgCost(endTime - startTime); - messageLogger.info("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", + MESSAGE_LOGGER.info("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, replyMQCluster + "-" + EventMeshConstants.RR_REPLY_TOPIC, origTopic, bizNo, uniqueId); } @@ -226,26 +222,26 @@ public void onSuccess(SendResult sendResult) { @Override public void onException(OnExceptionContext context) { HttpCommand err = request.createHttpCommandResponse( - replyMessageResponseHeader, - ReplyMessageResponseBody.buildBody(EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getRetCode(), + replyMessageResponseHeader, + ReplyMessageResponseBody.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(); summaryMetrics.recordReplyMsgFailed(); summaryMetrics.recordReplyMsgCost(endTime - startTime); - messageLogger.error("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", + MESSAGE_LOGGER.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) { completeResponse(request, asyncContext, replyMessageResponseHeader, - EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR, - EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(ex, 2), - ReplyMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR, + EventMeshRetCode.EVENTMESH_REPLY_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(ex, 2), + ReplyMessageResponseBody.class); long endTime = System.currentTimeMillis(); - messageLogger.error("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", + MESSAGE_LOGGER.error("message|eventMesh2mq|RSP|SYNC|reply2MQCost={}|topic={}|origTopic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, replyTopic, origTopic, bizNo, uniqueId, ex); summaryMetrics.recordReplyMsgFailed(); summaryMetrics.recordReplyMsgCost(endTime - startTime); 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 index 13d0c8db48..2768e0e31f 100644 --- 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 @@ -21,7 +21,7 @@ import org.apache.eventmesh.api.SendResult; import org.apache.eventmesh.api.exception.AclException; import org.apache.eventmesh.api.exception.OnExceptionContext; -import org.apache.eventmesh.api.registry.bo.EventMeshServicePubTopicInfo; +import org.apache.eventmesh.api.meta.bo.EventMeshServicePubTopicInfo; import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.protocol.ProtocolTransportObject; import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; @@ -29,7 +29,9 @@ 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.filter.pattern.Pattern; import org.apache.eventmesh.protocol.api.ProtocolAdaptor; import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; import org.apache.eventmesh.runtime.acl.Acl; @@ -37,11 +39,12 @@ 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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.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.eventmesh.transformer.Transformer; import org.apache.commons.lang3.StringUtils; @@ -57,10 +60,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.HttpRequest; - import lombok.extern.slf4j.Slf4j; - @Slf4j @EventMeshTrace(isEnable = true) public class SendAsyncEventProcessor implements AsyncHttpProcessor { @@ -83,15 +84,13 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final String localAddress = IPUtils.getLocalAddress(); - if (log.isInfoEnabled()) { - log.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), - EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), localAddress); - } + log.info("uri={}|{}|client2eventMesh|from={}|to={}", + requestWrapper.getRequestURI(), EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), localAddress); // user request header final Map requestHeaderMap = requestWrapper.getHeaderMap(); final String source = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - requestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, source); + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP.getKey(), source); // build sys header requestWrapper.buildSysHeaderForClient(); @@ -100,15 +99,15 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final requestHeaderMap.putIfAbsent("source", source); requestWrapper.buildSysHeaderForCE(); - final String bizNo = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.BIZSEQNO, - RandomStringUtils.generateNum(30)).toString(); - final String uniqueId = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.UNIQUEID, - RandomStringUtils.generateNum(30)).toString(); + final String bizNo = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.BIZSEQNO.getKey(), + RandomStringUtils.generateNum(32)).toString(); + final String uniqueId = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.UNIQUEID.getKey(), + RandomStringUtils.generateNum(32)).toString(); final String ttl = requestHeaderMap.getOrDefault(Constants.EVENTMESH_MESSAGE_CONST_TTL, - 4 * 1000).toString(); + 14400000).toString(); - requestWrapper.getSysHeaderMap().putIfAbsent(ProtocolKey.ClientInstanceKey.BIZSEQNO, bizNo); - requestWrapper.getSysHeaderMap().putIfAbsent(ProtocolKey.ClientInstanceKey.UNIQUEID, uniqueId); + requestWrapper.getSysHeaderMap().putIfAbsent(ProtocolKey.ClientInstanceKey.BIZSEQNO.getKey(), bizNo); + requestWrapper.getSysHeaderMap().putIfAbsent(ProtocolKey.ClientInstanceKey.UNIQUEID.getKey(), uniqueId); requestWrapper.getSysHeaderMap().putIfAbsent(Constants.EVENTMESH_MESSAGE_CONST_TTL, ttl); final Map responseHeaderMap = new HashMap<>(); @@ -132,7 +131,7 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final CloudEvent event = httpProtocolAdaptor.toCloudEvent(requestWrapper); - //validate event + // validate event if (event == null || event.getSource() == null || event.getSpecVersion() == null @@ -144,11 +143,11 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final return; } - final String idc = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.IDC)).toString(); - final String pid = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PID)).toString(); - final String sys = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS)).toString(); + final String idc = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.IDC.getKey())).toString(); + final String pid = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PID.getKey())).toString(); + final String sys = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS.getKey())).toString(); - //validate event-extension + // validate event-extension if (StringUtils.isAnyBlank(idc, pid, sys) || !StringUtils.isNumeric(pid)) { @@ -157,10 +156,14 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final return; } - final String producerGroup = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.PRODUCERGROUP)).toString(); + final String producerGroup = Objects.requireNonNull( + event.getExtension(ProtocolKey.ClientInstanceKey.PRODUCERGROUP.getKey())).toString(); final String topic = event.getSubject(); - //validate body + Pattern filterPattern = eventMeshHTTPServer.getFilterEngine().getFilterPattern(producerGroup + "-" + topic); + Transformer transformer = eventMeshHTTPServer.getTransformerEngine().getTransformer(producerGroup + "-" + topic); + + // validate body if (StringUtils.isAnyBlank(bizNo, uniqueId, producerGroup, topic) || event.getData() == null) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, responseHeaderMap, @@ -168,12 +171,12 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final return; } - final String token = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.TOKEN)).toString(); - //do acl check + final String token = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.TOKEN.getKey())).toString(); + // do acl check if (eventMeshHTTPServer.getEventMeshHttpConfiguration().isEventMeshServerSecurityEnable()) { final String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); final String requestURI = requestWrapper.getRequestURI(); - String subsystem = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS)).toString(); + String subsystem = Objects.requireNonNull(event.getExtension(ProtocolKey.ClientInstanceKey.SYS.getKey())).toString(); try { EventMeshServicePubTopicInfo eventMeshServicePubTopicInfo = eventMeshHTTPServer.getEventMeshServer() .getProducerTopicManager().getEventMeshServicePubTopicInfo(producerGroup); @@ -184,9 +187,7 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final } catch (Exception e) { handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_ACL_ERR, responseHeaderMap, responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); - if (log.isWarnEnabled()) { - log.warn("CLIENT HAS NO PERMISSION,SendAsyncMessageProcessor send failed", e); - } + log.warn("CLIENT HAS NO PERMISSION,SendAsyncMessageProcessor send failed", e); return; } } @@ -214,10 +215,7 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final String content = new String(Objects.requireNonNull(event.getData()).toBytes(), StandardCharsets.UTF_8); if (Objects.requireNonNull(content).length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEventSize()) { - if (log.isErrorEnabled()) { - log.error("Event size exceeds the limit: {}", - eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEventSize()); - } + log.error("Event size exceeds the limit: {}", eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEventSize()); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_SIZE_ERR, responseHeaderMap, responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); return; @@ -230,13 +228,9 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) .build(); - if (log.isDebugEnabled()) { - log.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); - } + log.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e); - } + log.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR, responseHeaderMap, responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); return; @@ -247,54 +241,68 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordSendMsg(); final long startTime = System.currentTimeMillis(); - + boolean isFiltered = true; 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); + if (filterPattern != null) { + isFiltered = filterPattern.filter(JsonUtils.toJSONString(event)); + } + + // apply transformer + if (isFiltered && transformer != null) { + String data = transformer.transform(JsonUtils.toJSONString(event)); + event = CloudEventBuilder.from(event).withData(Objects.requireNonNull(JsonUtils.toJSONString(data)) + .getBytes(StandardCharsets.UTF_8)).build(); + sendMessageContext.setEvent(event); + } - eventMeshProducer.send(sendMessageContext, new SendCallback() { + if (isFiltered) { + eventMeshProducer.send(sendMessageContext, new SendCallback() { - @Override - public void onSuccess(final SendResult sendResult) { - responseBodyMap.put(EventMeshConstants.RET_CODE, EventMeshRetCode.SUCCESS.getRetCode()); - responseBodyMap.put(EventMeshConstants.RET_MSG, EventMeshRetCode.SUCCESS.getErrMsg() + sendResult); + @Override + public void onSuccess(final SendResult sendResult) { + responseBodyMap.put(EventMeshConstants.RET_CODE, EventMeshRetCode.SUCCESS.getRetCode()); + responseBodyMap.put(EventMeshConstants.RET_MSG, EventMeshRetCode.SUCCESS.getErrMsg() + sendResult); - if (log.isInfoEnabled()) { log.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); } - handlerSpecific.getTraceOperation().endLatestTrace(sendMessageContext.getEvent()); - handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); - } - @Override - public void onException(final OnExceptionContext context) { - responseBodyMap.put(EventMeshConstants.RET_CODE, EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode()); - responseBodyMap.put(EventMeshConstants.RET_MSG, EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg() - + EventMeshUtil.stackTrace(context.getException(), 2)); - eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10_000)); - handlerSpecific.getTraceOperation().exceptionLatestTrace(context.getException(), - EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), sendMessageContext.getEvent())); - - handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); - if (log.isErrorEnabled()) { + @Override + public void onException(final OnExceptionContext context) { + responseBodyMap.put(EventMeshConstants.RET_CODE, EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode()); + responseBodyMap.put(EventMeshConstants.RET_MSG, EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg() + + EventMeshUtil.stackTrace(context.getException(), 2)); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); + handlerSpecific.getTraceOperation().exceptionLatestTrace(context.getException(), + EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), sendMessageContext.getEvent())); + + handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", System.currentTimeMillis() - startTime, topic, bizNo, uniqueId, context.getException()); } - } - }); + }); + } else { + log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}|apply filter failed", + System.currentTimeMillis() - startTime, topic, bizNo, uniqueId); + handlerSpecific.getTraceOperation().endLatestTrace(sendMessageContext.getEvent()); + handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_FILTER_MSG_ERR, responseHeaderMap, responseBodyMap, + EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); + } + } catch (Exception ex) { - eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10_000)); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR, responseHeaderMap, responseBodyMap, null); final long endTime = System.currentTimeMillis(); - if (log.isErrorEnabled()) { - log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", - endTime - startTime, topic, bizNo, uniqueId, ex); - } + log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + endTime - startTime, topic, bizNo, uniqueId, ex); } } 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 index 6fceaa20be..332f69ce3f 100644 --- 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 @@ -41,8 +41,8 @@ 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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; import org.apache.eventmesh.runtime.util.EventMeshUtil; import org.apache.eventmesh.runtime.util.RemotingHelper; import org.apache.eventmesh.runtime.util.TraceUtils; @@ -89,9 +89,9 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext HttpCommand request = asyncContext.getRequest(); String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); CMD_LOGGER.info("cmd={}|{}|client2eventMesh|from={}|to={}", RequestCode.get( - Integer.valueOf(request.getRequestCode())), - EventMeshConstants.PROTOCOL_HTTP, - remoteAddr, localAddress); + Integer.valueOf(request.getRequestCode())), + EventMeshConstants.PROTOCOL_HTTP, + remoteAddr, localAddress); SendMessageRequestHeader sendMessageRequestHeader = (SendMessageRequestHeader) request.getHeader(); @@ -109,26 +109,26 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext CloudEvent event = httpCommandProtocolAdaptor.toCloudEvent(request); Span span = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), - EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, true); + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, true); - //validate event + // validate event if (!ObjectUtils.allNotNull(event, event.getSource(), event.getSpecVersion()) || StringUtils.isAnyBlank(event.getId(), event.getType(), event.getSubject())) { completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageResponseBody.class); spanWithException(event, protocolVersion, EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR); return; } - String idc = getExtension(event, ProtocolKey.ClientInstanceKey.IDC); - String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID); - String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS); + String idc = getExtension(event, ProtocolKey.ClientInstanceKey.IDC.getKey()); + String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID.getKey()); + String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS.getKey()); - //validate event-extension + // validate event-extension if (StringUtils.isAnyBlank(idc, pid, sys) || !StringUtils.isNumeric(pid)) { completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR, null, SendMessageResponseBody.class); spanWithException(event, protocolVersion, EventMeshRetCode.EVENTMESH_PROTOCOL_HEADER_ERR); return; } @@ -138,26 +138,26 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext String producerGroup = getExtension(event, SendMessageRequestBody.PRODUCERGROUP); String topic = event.getSubject(); - //validate body + // validate body if (StringUtils.isAnyBlank(bizNo, uniqueId, producerGroup, topic) || event.getData() == null) { completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, null, SendMessageResponseBody.class); spanWithException(event, protocolVersion, EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR); return; } - //do acl check + // do acl check if (eventMeshHttpConfiguration.isEventMeshServerSecurityEnable()) { - String user = getExtension(event, ProtocolKey.ClientInstanceKey.USERNAME); - String pass = getExtension(event, ProtocolKey.ClientInstanceKey.PASSWD); - String subsystem = getExtension(event, ProtocolKey.ClientInstanceKey.SYS); + String user = getExtension(event, ProtocolKey.ClientInstanceKey.USERNAME.getKey()); + String pass = getExtension(event, ProtocolKey.ClientInstanceKey.PASSWD.getKey()); + String subsystem = getExtension(event, ProtocolKey.ClientInstanceKey.SYS.getKey()); int requestCode = Integer.parseInt(request.getRequestCode()); try { this.acl.doAclCheckInHttpSend(remoteAddr, user, pass, subsystem, topic, requestCode); } catch (Exception e) { completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_ACL_ERR, e.getMessage(), SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_ACL_ERR, e.getMessage(), SendMessageResponseBody.class); ACL_LOGGER.warn("CLIENT HAS NO PERMISSION,SendAsyncMessageProcessor send failed", e); spanWithException(event, protocolVersion, EventMeshRetCode.EVENTMESH_ACL_ERR); @@ -170,7 +170,7 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext if (!eventMeshHTTPServer.getMsgRateLimiter() .tryAcquire(EventMeshConstants.DEFAULT_FASTFAIL_TIMEOUT_IN_MILLISECONDS, TimeUnit.MILLISECONDS)) { completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR, null, SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR, null, SendMessageResponseBody.class); summaryMetrics.recordHTTPDiscard(); spanWithException(event, protocolVersion, EventMeshRetCode.EVENTMESH_HTTP_MES_SEND_OVER_LIMIT_ERR); @@ -181,7 +181,7 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext if (!eventMeshProducer.isStarted()) { completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR, null, SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR, null, SendMessageResponseBody.class); spanWithException(event, protocolVersion, EventMeshRetCode.EVENTMESH_GROUP_PRODUCER_STOPED_ERR); return; @@ -198,9 +198,9 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext HTTP_LOGGER.error("Event size exceeds the limit: {}", eventMeshHttpConfiguration.getEventMeshEventSize()); completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_SIZE_ERR, - "Event size exceeds the limit: " + eventMeshHttpConfiguration.getEventMeshEventSize(), - SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_SIZE_ERR, + "Event size exceeds the limit: " + eventMeshHttpConfiguration.getEventMeshEventSize(), + SendMessageResponseBody.class); spanWithException(event, protocolVersion, EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_SIZE_ERR); return; } @@ -212,15 +212,13 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext .withExtension(EventMeshConstants.REQ_SEND_EVENTMESH_IP, eventMeshHttpConfiguration.getEventMeshServerIp()) .build(); - if (MESSAGE_LOGGER.isDebugEnabled()) { - MESSAGE_LOGGER.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); - } + MESSAGE_LOGGER.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); } catch (Exception e) { MESSAGE_LOGGER.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e); completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR, - EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2), - SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR, + EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2), + SendMessageResponseBody.class); spanWithException(event, protocolVersion, EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR); return; } @@ -233,15 +231,13 @@ public void processRequest(ChannelHandlerContext ctx, AsyncContext final CompleteHandler handler = httpCommand -> { try { - if (HTTP_LOGGER.isDebugEnabled()) { - HTTP_LOGGER.debug("{}", httpCommand); - } + HTTP_LOGGER.debug("{}", httpCommand); eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); summaryMetrics.recordHTTPReqResTimeCost( System.currentTimeMillis() - request.getReqTime()); } catch (Exception ex) { - //ignore + // ignore } }; @@ -261,7 +257,7 @@ public void onSuccess(SendResult sendResult) { HttpCommand succ = request.createHttpCommandResponse( sendMessageResponseHeader, SendMessageResponseBody.buildBody(EventMeshRetCode.SUCCESS.getRetCode(), - EventMeshRetCode.SUCCESS.getErrMsg() + sendResult.toString())); + EventMeshRetCode.SUCCESS.getErrMsg() + sendResult)); asyncContext.onComplete(succ, handler); long endTime = System.currentTimeMillis(); summaryMetrics.recordSendMsgCost(endTime - startTime); @@ -280,7 +276,7 @@ public void onException(OnExceptionContext context) { + EventMeshUtil.stackTrace(context.getException(), 2))); asyncContext.onComplete(err, handler); - eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); long endTime = System.currentTimeMillis(); summaryMetrics.recordSendMsgFailed(); summaryMetrics.recordSendMsgCost(endTime - startTime); @@ -296,13 +292,12 @@ public void onException(OnExceptionContext context) { TraceUtils.finishSpan(clientSpan, event); } - } catch (Exception ex) { completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR, null, SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR, null, SendMessageResponseBody.class); spanWithException(event, protocolVersion, EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR); - eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10000)); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); long endTime = System.currentTimeMillis(); MESSAGE_LOGGER.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", endTime - startTime, topic, bizNo, uniqueId, ex); @@ -313,8 +308,8 @@ public void onException(OnExceptionContext context) { private void spanWithException(CloudEvent event, String protocolVersion, EventMeshRetCode retCode) { Span excepSpan = TraceUtils.prepareServerSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), - EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); + EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_SERVER_SPAN, false); TraceUtils.finishSpanWithException(excepSpan, EventMeshUtil.getCloudEventExtensionMap(protocolVersion, event), - retCode.getErrMsg(), null); + retCode.getErrMsg(), null); } } 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 index c6ea1a93c6..44c7cf1d46 100644 --- 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 @@ -17,7 +17,6 @@ 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; @@ -37,8 +36,8 @@ 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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; import org.apache.eventmesh.runtime.util.EventMeshUtil; import org.apache.eventmesh.runtime.util.RemotingHelper; import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; @@ -87,10 +86,8 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final HttpEventWrapper requestWrapper = asyncContext.getRequest(); final String localAddress = IPUtils.getLocalAddress(); - if (log.isInfoEnabled()) { - log.info("uri={}|{}|client2eventMesh|from={}|to={}", requestWrapper.getRequestURI(), - EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), localAddress); - } + log.info("uri={}|{}|client2eventMesh|from={}|to={}", + requestWrapper.getRequestURI(), EventMeshConstants.PROTOCOL_HTTP, RemotingHelper.parseChannelRemoteAddr(ctx.channel()), localAddress); // user request header final Map requestHeaderMap = requestWrapper.getHeaderMap(); @@ -106,14 +103,14 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final .append('-') .append(eventMeshHTTPServer.getEventMeshHttpConfiguration().getSysID()) .toString(); - requestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, source); - requestHeaderMap.put(ProtocolKey.ClientInstanceKey.ENV, + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.IP.getKey(), source); + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.ENV.getKey(), eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEnv()); - requestHeaderMap.put(ProtocolKey.ClientInstanceKey.IDC, + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.IDC.getKey(), eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshIDC()); - requestHeaderMap.put(ProtocolKey.ClientInstanceKey.SYS, + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.SYS.getKey(), eventMeshHTTPServer.getEventMeshHttpConfiguration().getSysID()); - requestHeaderMap.put(ProtocolKey.ClientInstanceKey.PRODUCERGROUP, meshGroup); + requestHeaderMap.put(ProtocolKey.ClientInstanceKey.PRODUCERGROUP.getKey(), meshGroup); // build sys header requestWrapper.buildSysHeaderForClient(); @@ -132,15 +129,15 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final requestWrapper.setBody(bodyMap.get("content").toString().getBytes(StandardCharsets.UTF_8)); - final String bizNo = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.BIZSEQNO, + final String bizNo = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.BIZSEQNO.getKey(), RandomStringUtils.generateNum(30)).toString(); - final String uniqueId = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.UNIQUEID, + final String uniqueId = requestHeaderMap.getOrDefault(ProtocolKey.ClientInstanceKey.UNIQUEID.getKey(), RandomStringUtils.generateNum(30)).toString(); final 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(ProtocolKey.ClientInstanceKey.BIZSEQNO.getKey(), bizNo); + requestWrapper.getSysHeaderMap().putIfAbsent(ProtocolKey.ClientInstanceKey.UNIQUEID.getKey(), uniqueId); requestWrapper.getSysHeaderMap().putIfAbsent(Constants.EVENTMESH_MESSAGE_CONST_TTL, ttl); final Map responseHeaderMap = new HashMap<>(); @@ -168,7 +165,7 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final ProtocolAdaptor httpProtocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor(protocolType); CloudEvent event = httpProtocolAdaptor.toCloudEvent(requestWrapper); - //validate event + // validate event if (event == null || StringUtils.isBlank(event.getId()) || event.getSource() == null @@ -182,11 +179,11 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final return; } - final String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID); - final String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS); + final String pid = getExtension(event, ProtocolKey.ClientInstanceKey.PID.getKey()); + final String sys = getExtension(event, ProtocolKey.ClientInstanceKey.SYS.getKey()); - //validate event-extension - if (StringUtils.isBlank(getExtension(event, ProtocolKey.ClientInstanceKey.IDC)) + // validate event-extension + if (StringUtils.isBlank(getExtension(event, ProtocolKey.ClientInstanceKey.IDC.getKey())) || StringUtils.isBlank(pid) || !StringUtils.isNumeric(pid) || StringUtils.isBlank(sys)) { @@ -195,10 +192,10 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final return; } - final String producerGroup = getExtension(event, ProtocolKey.ClientInstanceKey.PRODUCERGROUP); + final String producerGroup = getExtension(event, ProtocolKey.ClientInstanceKey.PRODUCERGROUP.getKey()); final String topic = event.getSubject(); - //validate body + // validate body if (StringUtils.isBlank(bizNo) || StringUtils.isBlank(uniqueId) || StringUtils.isBlank(producerGroup) @@ -209,13 +206,13 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final return; } - //do acl check + // do acl check if (eventMeshHTTPServer.getEventMeshHttpConfiguration().isEventMeshServerSecurityEnable()) { try { this.acl.doAclCheckInHttpSend(RemotingHelper.parseChannelRemoteAddr(ctx.channel()), - getExtension(event, ProtocolKey.ClientInstanceKey.USERNAME), - getExtension(event, ProtocolKey.ClientInstanceKey.PASSWD), - getExtension(event, ProtocolKey.ClientInstanceKey.SYS), + getExtension(event, ProtocolKey.ClientInstanceKey.USERNAME.getKey()), + getExtension(event, ProtocolKey.ClientInstanceKey.PASSWD.getKey()), + getExtension(event, ProtocolKey.ClientInstanceKey.SYS.getKey()), topic, requestWrapper.getRequestURI()); } catch (Exception e) { @@ -245,10 +242,7 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final final String content = event.getData() == null ? "" : new String(event.getData().toBytes(), StandardCharsets.UTF_8); if (content.length() > eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEventSize()) { - if (log.isErrorEnabled()) { - log.error("Event size exceeds the limit: {}", - eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEventSize()); - } + log.error("Event size exceeds the limit: {}", eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshEventSize()); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_SIZE_ERR, responseHeaderMap, responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); return; @@ -261,13 +255,9 @@ public void handler(final HandlerService.HandlerSpecific handlerSpecific, final .withExtension(EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, String.valueOf(System.currentTimeMillis())) .build(); - if (log.isDebugEnabled()) { - log.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); - } + log.debug("msg2MQMsg suc, bizSeqNo={}, topic={}", bizNo, topic); } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e); - } + log.error("msg2MQMsg err, bizSeqNo={}, topic={}", bizNo, topic, e); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_PACKAGE_MSG_ERR, responseHeaderMap, responseBodyMap, EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), event)); return; @@ -293,10 +283,8 @@ public void onSuccess(final SendResult sendResult) { responseBodyMap.put(EventMeshConstants.RET_CODE, EventMeshRetCode.SUCCESS.getRetCode()); responseBodyMap.put(EventMeshConstants.RET_MSG, EventMeshRetCode.SUCCESS.getErrMsg() + sendResult); - if (log.isInfoEnabled()) { - log.info("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", - System.currentTimeMillis() - startTime, topic, bizNo, uniqueId); - } + log.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); } @@ -306,27 +294,23 @@ public void onException(final OnExceptionContext context) { responseBodyMap.put(EventMeshConstants.RET_CODE, EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getRetCode()); responseBodyMap.put(EventMeshConstants.RET_MSG, EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR.getErrMsg() + EventMeshUtil.stackTrace(context.getException(), 2)); - eventMeshHTTPServer.getHttpRetryer().pushRetry(sendMessageContext.delay(10_000)); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); handlerSpecific.getTraceOperation().exceptionLatestTrace(context.getException(), EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), sendMessageContext.getEvent())); handlerSpecific.sendResponse(responseHeaderMap, responseBodyMap); - if (log.isErrorEnabled()) { - log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", - System.currentTimeMillis() - startTime, topic, bizNo, uniqueId, context.getException()); - } + log.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(10_000)); + eventMeshHTTPServer.getHttpRetryer().newTimeout(sendMessageContext, 10, TimeUnit.SECONDS); handlerSpecific.sendErrorResponse(EventMeshRetCode.EVENTMESH_SEND_ASYNC_MSG_ERR, responseHeaderMap, responseBodyMap, null); - if (log.isErrorEnabled()) { - log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", - System.currentTimeMillis() - startTime, topic, bizNo, uniqueId, ex); - } + log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|bizSeqNo={}|uniqueId={}", + System.currentTimeMillis() - startTime, topic, bizNo, uniqueId, ex); } } 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 index 12ba0c32a6..529cf66549 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.runtime.core.protocol.http.processor; - import org.apache.eventmesh.api.RequestReplyCallback; import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.protocol.ProtocolTransportObject; @@ -41,8 +40,8 @@ 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.core.protocol.producer.EventMeshProducer; +import org.apache.eventmesh.runtime.core.protocol.producer.SendMessageContext; import org.apache.eventmesh.runtime.util.EventMeshUtil; import org.apache.eventmesh.runtime.util.RemotingHelper; @@ -78,11 +77,8 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext eventMeshEventSize) { - if (log.isErrorEnabled()) { - log.error("Event size exceeds the limit: {}", eventMeshEventSize); - } + log.error("Event size exceeds the limit: {}", eventMeshEventSize); completeResponse(request, asyncContext, sendMessageResponseHeader, - EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, - "Event size exceeds the limit: " + eventMeshEventSize, - SendMessageResponseBody.class); + EventMeshRetCode.EVENTMESH_PROTOCOL_BODY_ERR, + "Event size exceeds the limit: " + eventMeshEventSize, + SendMessageResponseBody.class); return; } @@ -179,42 +171,36 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext handler = httpCommand -> { try { - if (log.isDebugEnabled()) { - log.debug("{}", httpCommand); - } + log.debug("{}", httpCommand); eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordHTTPReqResTimeCost( System.currentTimeMillis() - asyncContext.getRequest().getReqTime()); @@ -226,13 +212,11 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext subTopicList = subscribeRequestBody.getTopics(); - //do acl check + // do acl check if (eventMeshHttpConfiguration.isEventMeshServerSecurityEnable()) { for (final SubscriptionItem item : subTopicList) { try { @@ -116,10 +113,8 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext handler = httpCommand -> { try { - if (log.isDebugEnabled()) { - log.debug("{}", httpCommand); - } + log.debug("{}", httpCommand); eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); summaryMetrics.recordHTTPReqResTimeCost(System.currentTimeMillis() - request.getReqTime()); @@ -191,20 +182,16 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext handler = httpCommand -> { try { - if (log.isDebugEnabled()) { - log.debug("{}", httpCommand); - } + log.debug("{}", httpCommand); eventMeshHTTPServer.sendResponse(ctx, httpCommand.httpResponse()); summaryMetrics.recordHTTPReqResTimeCost(System.currentTimeMillis() - request.getReqTime()); } catch (Exception ex) { @@ -126,7 +120,7 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext localConsumerGroupMap = - subscriptionManager.getLocalConsumerGroupMapping(); + subscriptionManager.getLocalConsumerGroupMapping(); synchronized (subscriptionManager.getLocalClientInfoMapping()) { boolean isChange = true; @@ -141,14 +135,12 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext> idcUrls = new HashMap<>(); final Set clientUrls = new HashSet<>(); for (final Client client : groupTopicClients) { @@ -188,31 +180,29 @@ public void processRequest(final ChannelHandlerContext ctx, final AsyncContext StringUtils.equals(consumerGroup, s)); } catch (Exception e) { completeResponse(request, asyncContext, unSubscribeResponseHeader, - EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR, - EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2), - UnSubscribeResponseBody.class); + EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR, + EventMeshRetCode.EVENTMESH_UNSUBSCRIBE_ERR.getErrMsg() + EventMeshUtil.stackTrace(e, 2), + UnSubscribeResponseBody.class); final long endTime = System.currentTimeMillis(); - log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms" - + "|topic={}|url={}", endTime - startTime, - JsonUtils.toJSONString(unSubscribeRequestBody.getTopics()), - unSubscribeRequestBody.getUrl(), e); + log.error("message|eventMesh2mq|REQ|ASYNC|send2MQCost={}ms|topic={}|url={}", endTime - startTime, + JsonUtils.toJSONString(unSubscribeRequestBody.getTopics()), unSubscribeRequestBody.getUrl(), e); summaryMetrics.recordSendMsgFailed(); summaryMetrics.recordSendMsgCost(endTime - startTime); } } + eventMeshHTTPServer.getSubscriptionManager().updateMetaData(); } } @@ -255,7 +244,7 @@ private void registerClient(final UnSubscribeRequestHeader unSubscribeRequestHea final String groupTopicKey = client.getConsumerGroup() + "@" + client.getTopic(); ConcurrentHashMap> localClientInfoMap = eventMeshHTTPServer.getSubscriptionManager() - .getLocalClientInfoMapping(); + .getLocalClientInfoMapping(); if (localClientInfoMap.containsKey(groupTopicKey)) { final List localClients = localClientInfoMap.get(groupTopicKey); boolean isContains = false; 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 index 15f222a8eb..256b149b33 100644 --- 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 @@ -19,6 +19,7 @@ import org.apache.eventmesh.runtime.common.EventMeshTrace; import org.apache.eventmesh.runtime.util.HttpResponseUtils; +import org.apache.eventmesh.webhook.api.WebHookOperationConstant; import org.apache.eventmesh.webhook.receive.WebHookController; import java.util.HashMap; @@ -33,14 +34,14 @@ import lombok.Setter; @EventMeshTrace(isEnable = true) -public class WebHookProcessor implements HttpProcessor { +public class WebHookProcessor implements ShortHttpProcessor { @Setter private WebHookController webHookController; @Override public String[] paths() { - return new String[]{"/webhook"}; + return new String[]{WebHookOperationConstant.CALLBACK_PATH_PREFIX}; } @Override 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 index 10925a29fd..02d6933f10 100644 --- 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 @@ -17,29 +17,27 @@ package org.apache.eventmesh.runtime.core.protocol.http.processor.inf; +import static org.apache.eventmesh.common.Constants.HTTP; import static org.apache.eventmesh.runtime.constants.EventMeshConstants.CONTENT_TYPE; -import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.config.CommonConfiguration; import org.apache.eventmesh.common.protocol.SubscriptionItem; import org.apache.eventmesh.common.protocol.http.HttpEventWrapper; import org.apache.eventmesh.common.protocol.http.common.ProtocolKey; import org.apache.eventmesh.common.utils.AssertUtils; -import org.apache.eventmesh.common.utils.ConfigurationContextUtil; 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.registry.nacos.constant.NacosConstant; +import org.apache.eventmesh.meta.nacos.constant.NacosConstant; 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.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.core.protocol.http.processor.AsyncHttpProcessor; -import org.apache.eventmesh.runtime.registry.Registry; +import org.apache.eventmesh.runtime.meta.MetaStorage; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; @@ -72,66 +70,20 @@ public AbstractEventProcessor(EventMeshHTTPServer eventMeshHTTPServer) { this.eventMeshHTTPServer = eventMeshHTTPServer; } - /** - * Add a topic with subscribers to the service's metadata. - */ - protected void updateMetadata() { - if (!eventMeshHTTPServer.getEventMeshHttpConfiguration().isEventMeshServerRegistryEnable()) { - return; - } - - try { - - Map metadata = new HashMap<>(1 << 4); - for (Map.Entry consumerGroupMap : - eventMeshHTTPServer.getSubscriptionManager().getLocalConsumerGroupMapping().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.toJSONString(consumerGroupMetadata)); - } - - eventMeshHTTPServer.getRegistry().registerMetadata(metadata); - - } catch (Exception e) { - log.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.isEventMeshServerRegistryEnable()) { + if (!httpConfiguration.isEventMeshServerMetaStorageEnable()) { return ""; } String targetMesh = ""; - Registry registry = eventMeshHTTPServer.getRegistry(); - List allEventMeshInfo = registry.findAllEventMeshInfo(); + MetaStorage metaStorage = eventMeshHTTPServer.getMetaStorage(); + List allEventMeshInfo = metaStorage.findAllEventMeshInfo(); String httpServiceName = - ConfigurationContextUtil.HTTP + "-" + NacosConstant.GROUP + "@@" + httpConfiguration.getEventMeshName() - + "-" + ConfigurationContextUtil.HTTP; + HTTP + "-" + NacosConstant.GROUP + "@@" + httpConfiguration.getEventMeshName() + + "-" + HTTP; for (EventMeshDataInfo eventMeshDataInfo : allEventMeshInfo) { if (!eventMeshDataInfo.getEventMeshName().equals(httpServiceName)) { continue; @@ -193,10 +145,10 @@ protected Map builderResponseHeaderMap(HttpEventWrapper requestW * @return Returns true if any is empty */ protected boolean validateSysHeader(Map sysHeaderMap) { - return StringUtils.isAnyBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC).toString(), - sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString(), - sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS).toString()) - || !StringUtils.isNumeric(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID).toString()); + return StringUtils.isAnyBlank(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.IDC.getKey()).toString(), + sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID.getKey()).toString(), + sysHeaderMap.get(ProtocolKey.ClientInstanceKey.SYS.getKey()).toString()) + || !StringUtils.isNumeric(sysHeaderMap.get(ProtocolKey.ClientInstanceKey.PID.getKey()).toString()); } /** @@ -206,9 +158,7 @@ protected boolean validateSysHeader(Map sysHeaderMap) { * @return any null then true */ protected boolean validatedRequestBodyMap(Map requestBodyMap) { - return requestBodyMap.get(EventMeshConstants.URL) == null - || requestBodyMap.get(EventMeshConstants.MANAGE_TOPIC) == null - || requestBodyMap.get(EventMeshConstants.CONSUMER_GROUP) == null; + return requestBodyMap.get(EventMeshConstants.MANAGE_TOPIC) == null; } @@ -223,15 +173,15 @@ protected Map builderRemoteHeaderMap(String localAddress) { String meshGroup = eventMeshHttpConfiguration.getMeshGroup(); Map remoteHeaderMap = new HashMap<>(); - remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.ENV, eventMeshHttpConfiguration.getEventMeshEnv()); - remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.IDC, eventMeshHttpConfiguration.getEventMeshIDC()); - remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.IP, localAddress); - remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PID, String.valueOf(ThreadUtils.getPID())); - remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.SYS, eventMeshHttpConfiguration.getSysID()); - remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.USERNAME, EventMeshConstants.USER_NAME); - remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PASSWD, EventMeshConstants.PASSWD); - remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PRODUCERGROUP, meshGroup); - remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.CONSUMERGROUP, meshGroup); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.ENV.getKey(), eventMeshHttpConfiguration.getEventMeshEnv()); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.IDC.getKey(), eventMeshHttpConfiguration.getEventMeshIDC()); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.IP.getKey(), localAddress); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PID.getKey(), String.valueOf(ThreadUtils.getPID())); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.SYS.getKey(), eventMeshHttpConfiguration.getSysID()); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.USERNAME.getKey(), EventMeshConstants.USER_NAME); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PASSWD.getKey(), EventMeshConstants.PASSWD); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.PRODUCERGROUP.getKey(), meshGroup); + remoteHeaderMap.put(ProtocolKey.ClientInstanceKey.CONSUMERGROUP.getKey(), meshGroup); return remoteHeaderMap; } @@ -250,7 +200,7 @@ public static String post(CloseableHttpClient client, String uri, Map requestHeader, Map requestBody, ResponseHandler responseHandler) throws IOException { AssertUtils.notNull(client, "client can't be null"); - AssertUtils.notBlack(uri, "uri can't be null"); + AssertUtils.notBlank(uri, "uri can't be null"); AssertUtils.notNull(requestHeader, "requestParam can't be null"); AssertUtils.notNull(responseHandler, "responseHandler can't be null"); @@ -258,18 +208,18 @@ public static String post(CloseableHttpClient client, String uri, httpPost.addHeader(CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType()); - //header + // header if (MapUtils.isNotEmpty(requestHeader)) { requestHeader.forEach(httpPost::addHeader); } - //body + // body if (MapUtils.isNotEmpty(requestBody)) { String jsonStr = Optional.ofNullable(JsonUtils.toJSONString(requestBody)).orElse(""); httpPost.setEntity(new StringEntity(jsonStr, ContentType.APPLICATION_JSON)); } - //ttl + // 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))) 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 index d6e81b6847..5cd63d8f5f 100644 --- 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 @@ -131,7 +131,6 @@ public Date getLastUpTime() { return lastUpTime; } - @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -149,4 +148,3 @@ public String toString() { return sb.toString(); } } - 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 index 893d35c559..570f11c998 100644 --- 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 @@ -48,14 +48,14 @@ default boolean rejectRequest() { return false; } - default void completeResponse(HttpCommand req, AsyncContext asyncContext, - T respHeader, EventMeshRetCode emCode, - String msg, Class clazz) { + default void completeResponse(HttpCommand req, AsyncContext asyncContext, + T respHeader, EventMeshRetCode emCode, + String msg, Class clazz) { try { Method method = clazz.getMethod("buildBody", Integer.class, String.class); Object o = method.invoke(null, emCode.getRetCode(), - StringUtils.isNotBlank(msg) ? msg : emCode.getErrMsg()); - HttpCommand response = req.createHttpCommandResponse(respHeader, (E) o); + StringUtils.isNotBlank(msg) ? msg : emCode.getErrMsg()); + HttpCommand response = req.createHttpCommandResponse(respHeader, (Body) o); asyncContext.onComplete(response); } catch (Exception e) { log.error("response failed", e); 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 deleted file mode 100644 index f58f20ea64..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/EventMeshProducer.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.runtime.core.protocol.http.producer; - -import org.apache.eventmesh.api.RequestReplyCallback; -import org.apache.eventmesh.api.SendCallback; -import org.apache.eventmesh.common.Constants; -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 org.apache.commons.lang3.StringUtils; - -import java.util.Properties; -import java.util.concurrent.atomic.AtomicBoolean; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class EventMeshProducer { - - protected AtomicBoolean started = new AtomicBoolean(Boolean.FALSE); - - protected AtomicBoolean inited = new AtomicBoolean(Boolean.FALSE); - - public AtomicBoolean getInited() { - return inited; - } - - public AtomicBoolean getStarted() { - return started; - } - - public boolean isStarted() { - return started.get(); - } - - protected ProducerGroupConf producerGroupConfig; - - protected EventMeshHTTPConfiguration eventMeshHttpConfiguration; - - protected MQProducerWrapper mqProducerWrapper; - - 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; - } - - public MQProducerWrapper getMqProducerWrapper() { - return mqProducerWrapper; - } - - public void init(EventMeshHTTPConfiguration eventMeshHttpConfiguration, - ProducerGroupConf producerGroupConfig) throws Exception { - if (!inited.compareAndSet(false, true)) { - return; - } - this.producerGroupConfig = producerGroupConfig; - this.eventMeshHttpConfiguration = eventMeshHttpConfiguration; - - Properties keyValue = new Properties(); - keyValue.put("producerGroup", producerGroupConfig.getGroupName()); - keyValue.put("instanceName", EventMeshUtil.buildMeshClientID(producerGroupConfig.getGroupName(), - eventMeshHttpConfiguration.getEventMeshCluster())); - if (StringUtils.isNotBlank(producerGroupConfig.getToken())) { - keyValue.put(Constants.PRODUCER_TOKEN, producerGroupConfig.getToken()); - } - - //TODO for defibus - keyValue.put("eventMeshIDC", eventMeshHttpConfiguration.getEventMeshIDC()); - mqProducerWrapper = new MQProducerWrapper(eventMeshHttpConfiguration.getEventMeshStoragePluginType()); - mqProducerWrapper.init(keyValue); - log.info("EventMeshProducer [{}] inited.............", producerGroupConfig.getGroupName()); - } - - - public void start() throws Exception { - - if (!started.compareAndSet(false, true)) { - return; - } - mqProducerWrapper.start(); - log.info("EventMeshProducer [{}] started.............", producerGroupConfig.getGroupName()); - } - - public void shutdown() throws Exception { - if (!inited.compareAndSet(true, false)) { - return; - } - if (!started.compareAndSet(true, false)) { - return; - } - mqProducerWrapper.shutdown(); - log.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 deleted file mode 100644 index 2e21ec2c24..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/ProducerManager.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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 lombok.extern.slf4j.Slf4j; - -@Slf4j -public class ProducerManager { - - private EventMeshHTTPServer eventMeshHTTPServer; - - private ConcurrentHashMap producerTable = new ConcurrentHashMap(); - - public ProducerManager(EventMeshHTTPServer eventMeshHTTPServer) { - this.eventMeshHTTPServer = eventMeshHTTPServer; - } - - public void init() throws Exception { - log.info("producerManager inited......"); - } - - public void start() throws Exception { - log.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.isStarted()) { - eventMeshProducer.start(); - } - - return eventMeshProducer; - } - - public EventMeshProducer getEventMeshProducer(String producerGroup, String token) throws Exception { - EventMeshProducer eventMeshProducer = null; - if (!producerTable.containsKey(producerGroup)) { - synchronized (producerTable) { - if (!producerTable.containsKey(producerGroup)) { - ProducerGroupConf producerGroupConfig = new ProducerGroupConf(producerGroup, token); - 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) { - log.error("shutdown eventMeshProducer[{}] err", eventMeshProducer, ex); - } - } - log.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/ProducerTopicManager.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/ProducerTopicManager.java index b37239d976..6201c21a33 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/ProducerTopicManager.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/ProducerTopicManager.java @@ -17,7 +17,7 @@ package org.apache.eventmesh.runtime.core.protocol.http.producer; -import org.apache.eventmesh.api.registry.bo.EventMeshServicePubTopicInfo; +import org.apache.eventmesh.api.meta.bo.EventMeshServicePubTopicInfo; import org.apache.eventmesh.common.EventMeshThreadFactory; import org.apache.eventmesh.common.ThreadPoolFactory; import org.apache.eventmesh.runtime.boot.EventMeshServer; @@ -58,10 +58,10 @@ public void start() { synchronized (ProducerTopicManager.class) { scheduledTask = scheduler.scheduleAtFixedRate(() -> { try { - if (!eventMeshServer.getConfiguration().isEventMeshServerRegistryEnable()) { + if (!eventMeshServer.getConfiguration().isEventMeshServerMetaStorageEnable()) { return; } - List pubTopicInfoList = eventMeshServer.getRegistry().findEventMeshServicePubTopicInfos(); + List pubTopicInfoList = eventMeshServer.getMetaStorage().findEventMeshServicePubTopicInfos(); Optional.ofNullable(pubTopicInfoList) .ifPresent(lt -> lt.forEach(item -> eventMeshServicePubTopicInfoMap.put(item.getService(), item))); } catch (Exception e) { @@ -89,5 +89,4 @@ public EventMeshServicePubTopicInfo getEventMeshServicePubTopicInfo(String produ return eventMeshServicePubTopicInfoMap.get(producerGroup); } - } 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 deleted file mode 100644 index 3334c26bdc..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/http/producer/SendMessageContext.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.RetryContext; - -import org.apache.commons.lang3.time.DateFormatUtils; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import io.cloudevents.CloudEvent; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class SendMessageContext extends RetryContext { - - 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_INCLUDE_MILLISECONDS)) - .append(",createTime=").append(DateFormatUtils.format(createTime, Constants.DATE_FORMAT_INCLUDE_MILLISECONDS)).append("}"); - return sb.toString(); - } - - @Override - public void retry() throws Exception { - if (eventMeshProducer == null) { - log.error("Exception happends during retry. EventMeshProduceer is null."); - return; - } - - if (retryTimes > 0) { //retry once - log.error("Exception happends during retry. The retryTimes > 0."); - return; - } - - retryTimes++; - eventMeshProducer.send(this, new SendCallback() { - - @Override - public void onSuccess(SendResult sendResult) { - } - - @Override - public void onException(OnExceptionContext context) { - log.warn("", context.getException()); - eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordSendBatchMsgFailed(1); - } - - }); - } -} 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 index 408d130b05..562c6ba014 100644 --- 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 @@ -23,6 +23,7 @@ import org.apache.eventmesh.runtime.core.protocol.RetryContext; 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.producer.ProducerManager; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; @@ -31,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import com.google.common.collect.Lists; @@ -43,7 +45,10 @@ public abstract class AbstractHTTPPushRequest extends RetryContext { public long lastPushTime = System.currentTimeMillis(); - public final Map> urls; + /** + * key: IDC + */ + public final Map> urls; public final List totalUrls; @@ -68,16 +73,16 @@ public AbstractHTTPPushRequest(HandleMsgContext handleMsgContext) { this.retryer = handleMsgContext.getEventMeshHTTPServer().getHttpRetryer(); this.ttl = handleMsgContext.getTtl(); this.startIdx = ThreadLocalRandom.current().nextInt(0, totalUrls.size()); + super.commonConfiguration = eventMeshHttpConfiguration; } public void tryHTTPRequest() { } - public void delayRetry(long delayTime) { + public void delayRetry(long delayTime, TimeUnit timeUnit) { if (retryTimes < EventMeshConstants.DEFAULT_PUSH_RETRY_TIMES && delayTime > 0) { retryTimes++; - delay(delayTime); - retryer.pushRetry(this); + retryer.newTimeout(this, delayTime, timeUnit); } else { complete.compareAndSet(Boolean.FALSE, Boolean.TRUE); } @@ -86,8 +91,7 @@ public void delayRetry(long delayTime) { public void delayRetry() { if (retryTimes < EventMeshConstants.DEFAULT_PUSH_RETRY_TIMES) { retryTimes++; - delay((long) retryTimes * EventMeshConstants.DEFAULT_PUSH_RETRY_TIME_DISTANCE_IN_MILLSECONDS); - retryer.pushRetry(this); + retryer.newTimeout(this, EventMeshConstants.DEFAULT_PUSH_RETRY_TIME_DISTANCE_IN_MILLSECONDS, TimeUnit.MILLISECONDS); } else { complete.compareAndSet(Boolean.FALSE, Boolean.TRUE); } @@ -125,4 +129,10 @@ public void timeout() { delayRetry(); } } + + @Override + protected ProducerManager getProducerManager() { + return eventMeshHTTPServer.getProducerManager(); + } + } 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 index f96e05f585..2d0a659e42 100644 --- 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 @@ -30,12 +30,14 @@ 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.filter.pattern.Pattern; 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.eventmesh.transformer.Transformer; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; @@ -51,6 +53,7 @@ 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; @@ -58,6 +61,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,6 +81,7 @@ public class AsyncHTTPPushRequest extends AbstractHTTPPushRequest { public static final Logger LOGGER = LoggerFactory.getLogger("AsyncHTTPPushRequest"); public String currPushUrl; + private final Map> waitingRequests; public AsyncHTTPPushRequest(HandleMsgContext handleMsgContext, @@ -91,6 +96,8 @@ public void tryHTTPRequest() { currPushUrl = getUrl(); if (StringUtils.isBlank(currPushUrl)) { + LOGGER.warn("tryHTTPRequest fail, getUrl is null, group:{}, topic:{}, bizSeqNo={}, uniqueId={}", this.handleMsgContext.getConsumerGroup(), + this.handleMsgContext.getTopic(), this.handleMsgContext.getBizSeqNo(), this.handleMsgContext.getUniqueId()); return; } @@ -121,7 +128,33 @@ public void tryHTTPRequest() { .withExtension(EventMeshConstants.RSP_URL, currPushUrl) .withExtension(EventMeshConstants.RSP_GROUP, handleMsgContext.getConsumerGroup()) .build(); + + Pattern filterPattern = eventMeshHTTPServer.getFilterEngine() + .getFilterPattern(handleMsgContext.getConsumerGroup() + "-" + handleMsgContext.getTopic()); + if (filterPattern != null) { + if (!filterPattern.filter(JsonUtils.toJSONString(event))) { + LOGGER.error("apply filter failed, group:{}, topic:{}, bizSeqNo={}, uniqueId={}", + this.handleMsgContext.getConsumerGroup(), + this.handleMsgContext.getTopic(), this.handleMsgContext.getBizSeqNo(), this.handleMsgContext.getUniqueId()); + return; + } + } + Transformer transformer = eventMeshHTTPServer.getTransformerEngine() + .getTransformer(handleMsgContext.getConsumerGroup() + "-" + handleMsgContext.getTopic()); + if (transformer != null) { + try { + String data = transformer.transform(JsonUtils.toJSONString(event)); + event = CloudEventBuilder.from(event).withData(Objects.requireNonNull(JsonUtils.toJSONString(data)) + .getBytes(StandardCharsets.UTF_8)).build(); + } catch (Exception exception) { + LOGGER.warn("apply transformer to cloudevents error, group:{}, topic:{}, bizSeqNo={}, uniqueId={}", + this.handleMsgContext.getConsumerGroup(), + this.handleMsgContext.getTopic(), this.handleMsgContext.getBizSeqNo(), this.handleMsgContext.getUniqueId(), exception); + return; + } + } handleMsgContext.setEvent(event); + super.setEvent(event); String content = ""; try { @@ -144,7 +177,9 @@ public void tryHTTPRequest() { } } catch (Exception ex) { - LOGGER.error("Failed to convert EventMeshMessage from CloudEvent", ex); + LOGGER.warn("cloudevent to HttpEventWrapper occur except, group:{}, topic:{}, bizSeqNo={}, uniqueId={}", + this.handleMsgContext.getConsumerGroup(), + this.handleMsgContext.getTopic(), this.handleMsgContext.getBizSeqNo(), this.handleMsgContext.getUniqueId(), ex); return; } @@ -181,8 +216,7 @@ public void tryHTTPRequest() { .get(handleMsgContext.getTopic()).getHttpAuthTypeMap().get(currPushUrl); WebhookUtil.setWebhookHeaders(builder, httpEntity.getContentType().getValue(), - eventMeshHttpConfiguration.getEventMeshWebhookOrigin(), - urlAuthType); + eventMeshHttpConfiguration.getEventMeshWebhookOrigin(), urlAuthType); eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordPushMsg(); @@ -190,10 +224,7 @@ public void tryHTTPRequest() { addToWaitingMap(this); - if (CMD_LOGGER.isInfoEnabled()) { - CMD_LOGGER.info("cmd={}|eventMesh2client|from={}|to={}", requestCode, - localAddress, currPushUrl); - } + CMD_LOGGER.info("cmd={}|eventMesh2client|from={}|to={}", requestCode, localAddress, currPushUrl); try { eventMeshHTTPServer.getHttpClientPool().getClient().execute(builder, response -> { @@ -207,46 +238,36 @@ public void tryHTTPRequest() { try { res = EntityUtils.toString(response.getEntity(), Charset.forName(EventMeshConstants.DEFAULT_CHARSET)); } catch (IOException e) { + LOGGER.warn("handleResponse exception", e); handleMsgContext.finish(); return new Object(); } ClientRetCode result = processResponseContent(res); - if (MESSAGE_LOGGER.isInfoEnabled()) { - MESSAGE_LOGGER.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(); - } + MESSAGE_LOGGER.info("message|eventMesh2client|{}|url={}|topic={}|bizSeqNo={}|uniqueId={}|cost={}", + result, currPushUrl, handleMsgContext.getTopic(), + handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), cost); + switch (result) { + case OK: + case REMOTE_OK: + case FAIL: + complete(); + if (isComplete()) { + handleMsgContext.finish(); + } + break; + case RETRY: + case NOLISTEN: + delayRetry(); + if (isComplete()) { + handleMsgContext.finish(); + } + break; + default: // do nothing } } else { eventMeshHTTPServer.getMetrics().getSummaryMetrics().recordHttpPushMsgFailed(); - if (MESSAGE_LOGGER.isInfoEnabled()) { - MESSAGE_LOGGER.info( - "message|eventMesh2client|exception|url={}|topic={}|bizSeqNo={}" - + "|uniqueId={}|cost={}", currPushUrl, handleMsgContext.getTopic(), - handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), cost); - } + MESSAGE_LOGGER.info("message|eventMesh2client|exception|url={}|topic={}|bizSeqNo={}|uniqueId={}|cost={}", + currPushUrl, handleMsgContext.getTopic(), handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), cost); if (isComplete()) { handleMsgContext.finish(); @@ -256,16 +277,11 @@ public void tryHTTPRequest() { }); if (MESSAGE_LOGGER.isDebugEnabled()) { - MESSAGE_LOGGER.debug("message|eventMesh2client|url={}|topic={}|event={}", currPushUrl, - handleMsgContext.getTopic(), - handleMsgContext.getEvent()); + MESSAGE_LOGGER.debug("message|eventMesh2client|url={}|topic={}|event={}", + currPushUrl, handleMsgContext.getTopic(), handleMsgContext.getEvent()); } else { - if (MESSAGE_LOGGER.isInfoEnabled()) { - MESSAGE_LOGGER - .info("message|eventMesh2client|url={}|topic={}|bizSeqNo={}|uniqueId={}", - currPushUrl, handleMsgContext.getTopic(), - handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId()); - } + MESSAGE_LOGGER.info("message|eventMesh2client|url={}|topic={}|bizSeqNo={}|uniqueId={}", + currPushUrl, handleMsgContext.getTopic(), handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId()); } } catch (IOException e) { MESSAGE_LOGGER.error("push2client err", e); @@ -306,7 +322,7 @@ boolean processResponseStatus(int httpStatus, HttpResponse httpResponse) { // 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())); + delayRetry(Long.parseLong(optHeader.get().getValue()), TimeUnit.MILLISECONDS); } return false; } else if (httpStatus == HttpStatus.SC_GONE || httpStatus == HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE) { @@ -319,6 +335,11 @@ boolean processResponseStatus(int httpStatus, HttpResponse httpResponse) { return false; } + @Override + protected HandleMsgContext getHandleMessageContext() { + return handleMsgContext; + } + ClientRetCode processResponseContent(String content) { if (StringUtils.isBlank(content)) { return ClientRetCode.FAIL; @@ -328,23 +349,19 @@ ClientRetCode processResponseContent(String content) { Map ret = JsonUtils.parseTypeReferenceObject(content, new TypeReference>() { }); - Integer retCode = (Integer) ret.get("retCode"); + Integer retCode = (Integer) Objects.requireNonNull(ret).get(ProtocolKey.RETCODE); if (retCode != null && ClientRetCode.contains(retCode)) { return ClientRetCode.get(retCode); } return ClientRetCode.FAIL; } catch (NumberFormatException e) { - if (MESSAGE_LOGGER.isWarnEnabled()) { - MESSAGE_LOGGER.warn("url:{}, bizSeqno:{}, uniqueId:{}, httpResponse:{}", currPushUrl, - handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), content); - } + MESSAGE_LOGGER.warn("url:{}, bizSeqno:{}, uniqueId:{}, httpResponse:{}", + currPushUrl, handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), content); return ClientRetCode.FAIL; - } catch (Throwable e) { - if (MESSAGE_LOGGER.isWarnEnabled()) { - MESSAGE_LOGGER.warn("url:{}, bizSeqno:{}, uniqueId:{}, httpResponse:{}", currPushUrl, - handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), content); - } + } catch (Exception e) { + MESSAGE_LOGGER.warn("url:{}, bizSeqno:{}, uniqueId:{}, httpResponse:{}", + currPushUrl, handleMsgContext.getBizSeqNo(), handleMsgContext.getUniqueId(), content); return ClientRetCode.FAIL; } } @@ -366,7 +383,7 @@ private void removeWaitingMap(AsyncHTTPPushRequest request) { } @Override - public void retry() { + public void doRun() { tryHTTPRequest(); } } 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 index fde09ae800..393b01d7f8 100644 --- 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 @@ -18,6 +18,7 @@ package org.apache.eventmesh.runtime.core.protocol.http.push; import org.apache.commons.collections4.CollectionUtils; +import org.apache.http.client.config.RequestConfig; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; @@ -47,7 +48,6 @@ import javax.net.ssl.SSLContext; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -60,6 +60,9 @@ public class HTTPClientPool { private static final int DEFAULT_MAX_TOTAL = 200; private static final int DEFAULT_IDLETIME_SECONDS = 30; + private static final int CONNECT_TIMEOUT = 5000; + private static final int SOCKET_TIMEOUT = 5000; + private transient PoolingHttpClientConnectionManager connectionManager; public HTTPClientPool(final int core) { @@ -91,7 +94,7 @@ public void shutdown() throws IOException { } } - //@SuppressWarnings("deprecation") + // @SuppressWarnings("deprecation") public CloseableHttpClient getHttpClient(final int maxTotal, final int idleTimeInSeconds, final SSLContext sslContext) { SSLContext innerSSLContext = sslContext; @@ -105,8 +108,7 @@ public CloseableHttpClient getHttpClient(final int maxTotal, final int idleTimeI if (connectionManager == null) { final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(innerSSLContext, NoopHostnameVerifier.INSTANCE); - final Registry socketFactoryRegistry - = RegistryBuilder.create() + final Registry socketFactoryRegistry = RegistryBuilder.create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslsf) .build(); @@ -115,7 +117,13 @@ public CloseableHttpClient getHttpClient(final int maxTotal, final int idleTimeI connectionManager.setMaxTotal(maxTotal); } + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(CONNECT_TIMEOUT) + .setConnectionRequestTimeout(CONNECT_TIMEOUT) + .setSocketTimeout(SOCKET_TIMEOUT).build(); + return HttpClients.custom() + .setDefaultRequestConfig(config) .setConnectionManager(connectionManager) .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) .evictIdleConnections(idleTimeInSeconds, TimeUnit.SECONDS) 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 index 3972cf451a..68ad9c5963 100644 --- 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 @@ -46,39 +46,36 @@ public class HTTPMessageHandler implements MessageHandler { private final transient EventMeshConsumer eventMeshConsumer; - private static final transient ScheduledExecutorService SCHEDULER = + private static final ScheduledExecutorService SCHEDULER = ThreadPoolFactory.createSingleScheduledExecutor("eventMesh-pushMsgTimeout"); private static final Integer CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD = 10000; - protected static final transient Map> waitingRequests = Maps.newConcurrentMap(); + protected static final Map> waitingRequests = Maps.newConcurrentMap(); private final transient ThreadPoolExecutor pushExecutor; private void checkTimeout() { - waitingRequests.forEach((key, value) -> - value.forEach(r -> { - r.timeout(); - waitingRequests.get(r.handleMsgContext.getConsumerGroup()).remove(r); - }) - ); + waitingRequests.forEach((key, value) -> value.forEach(r -> { + r.timeout(); + waitingRequests.get(r.handleMsgContext.getConsumerGroup()).remove(r); + })); } - public HTTPMessageHandler(EventMeshConsumer eventMeshConsumer) { this.eventMeshConsumer = eventMeshConsumer; - this.pushExecutor = eventMeshConsumer.getEventMeshHTTPServer().getPushMsgExecutor(); + this.pushExecutor = eventMeshConsumer.getEventMeshHTTPServer().getHttpThreadPoolGroup().getPushMsgExecutor(); waitingRequests.put(this.eventMeshConsumer.getConsumerGroupConf().getConsumerGroup(), Sets.newConcurrentHashSet()); SCHEDULER.scheduleAtFixedRate(this::checkTimeout, 0, 1000, TimeUnit.MILLISECONDS); } @Override public boolean handle(final HandleMsgContext handleMsgContext) { - if (MapUtils.getObject(waitingRequests, handleMsgContext.getConsumerGroup(), Sets.newConcurrentHashSet()).size() - > CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD) { + if (MapUtils.getObject(waitingRequests, handleMsgContext.getConsumerGroup(), Sets.newConcurrentHashSet()) + .size() > CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD) { log.warn("waitingRequests is too many, so reject, this message will be send back to MQ, " - + "consumerGroup:{}, threshold:{}", + + "consumerGroup:{}, threshold:{}", handleMsgContext.getConsumerGroup(), CONSUMER_GROUP_WAITING_REQUEST_THRESHOLD); return false; } @@ -88,7 +85,7 @@ public boolean handle(final HandleMsgContext handleMsgContext) { String protocolVersion = Objects.requireNonNull(handleMsgContext.getEvent().getSpecVersion()).toString(); Span span = TraceUtils.prepareClientSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, - handleMsgContext.getEvent()), + handleMsgContext.getEvent()), EventMeshTraceConstants.TRACE_DOWNSTREAM_EVENTMESH_CLIENT_SPAN, false); try { @@ -101,7 +98,7 @@ public boolean handle(final HandleMsgContext handleMsgContext) { return true; } catch (RejectedExecutionException e) { log.warn("pushMsgThreadPoolQueue is full, so reject, current task size {}", - handleMsgContext.getEventMeshHTTPServer().getPushMsgExecutor().getQueue().size(), e); + handleMsgContext.getEventMeshHTTPServer().getHttpThreadPoolGroup().getPushMsgExecutor().getQueue().size(), e); return false; } } 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 index 4e1be246d7..f081cc1595 100644 --- 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 @@ -17,98 +17,17 @@ package org.apache.eventmesh.runtime.core.protocol.http.retry; -import org.apache.eventmesh.common.EventMeshThreadFactory; +import org.apache.eventmesh.retry.api.AbstractRetryer; import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; -import org.apache.eventmesh.runtime.core.protocol.DelayRetryable; - -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; - import lombok.extern.slf4j.Slf4j; @Slf4j -public class HttpRetryer { - - private final Logger retryLogger = LoggerFactory.getLogger("retry"); +public class HttpRetryer extends AbstractRetryer { private final EventMeshHTTPServer eventMeshHTTPServer; public HttpRetryer(EventMeshHTTPServer eventMeshHTTPServer) { this.eventMeshHTTPServer = eventMeshHTTPServer; } - - private final DelayQueue failed = new DelayQueue<>(); - - private ThreadPoolExecutor pool; - - private Thread dispatcher; - - public void pushRetry(DelayRetryable delayRetryable) { - if (failed.size() >= eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshServerRetryBlockQSize()) { - retryLogger.error("[RETRY-QUEUE] is full!"); - return; - } - failed.offer(delayRetryable); - } - - public void init() { - pool = new ThreadPoolExecutor(eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshServerRetryThreadNum(), - eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshServerRetryThreadNum(), - 60000, - TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>( - eventMeshHTTPServer.getEventMeshHttpConfiguration().getEventMeshServerRetryBlockQSize()), - new EventMeshThreadFactory("http-retry", true, Thread.NORM_PRIORITY), - 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); - log.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(); - log.info("HttpRetryer shutdown......"); - } - - public void start() throws Exception { - dispatcher.start(); - log.info("HttpRetryer started......"); - } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/producer/EventMeshProducer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/producer/EventMeshProducer.java new file mode 100644 index 0000000000..bd27d6933d --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/producer/EventMeshProducer.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.producer; + +import org.apache.eventmesh.api.RequestReplyCallback; +import org.apache.eventmesh.api.SendCallback; +import org.apache.eventmesh.common.config.CommonConfiguration; +import org.apache.eventmesh.runtime.common.ServiceState; +import org.apache.eventmesh.runtime.constants.EventMeshConstants; +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 lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EventMeshProducer { + + 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(CommonConfiguration configuration, + ProducerGroupConf producerGroupConfig) throws Exception { + if (ServiceState.INITED == serviceState) { + return; + } + this.producerGroupConfig = producerGroupConfig; + + Properties keyValue = new Properties(); + keyValue.put(EventMeshConstants.PRODUCER_GROUP, producerGroupConfig.getGroupName()); + keyValue.put(EventMeshConstants.INSTANCE_NAME, EventMeshUtil.buildMeshClientID( + producerGroupConfig.getGroupName(), configuration.getEventMeshCluster())); + + // TODO for defibus + keyValue.put(EventMeshConstants.EVENT_MESH_IDC, configuration.getEventMeshIDC()); + mqProducerWrapper = new MQProducerWrapper( + configuration.getEventMeshStoragePluginType()); + mqProducerWrapper.init(keyValue); + serviceState = ServiceState.INITED; + log.info("EventMeshProducer [{}] inited...........", producerGroupConfig.getGroupName()); + } + + public synchronized void start() throws Exception { + if (serviceState == null || ServiceState.RUNNING == serviceState) { + return; + } + + mqProducerWrapper.start(); + serviceState = ServiceState.RUNNING; + log.info("EventMeshProducer [{}] started..........", producerGroupConfig.getGroupName()); + } + + public synchronized void shutdown() throws Exception { + if (serviceState == null || ServiceState.STOPPED == serviceState) { + return; + } + + mqProducerWrapper.shutdown(); + serviceState = ServiceState.STOPPED; + log.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(); + } + + public MQProducerWrapper getMqProducerWrapper() { + return mqProducerWrapper; + } + + public boolean isStarted() { + return serviceState == ServiceState.RUNNING; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/producer/ProducerManager.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/producer/ProducerManager.java new file mode 100644 index 0000000000..251790f89a --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/producer/ProducerManager.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.producer; + +import org.apache.eventmesh.runtime.boot.AbstractRemotingServer; +import org.apache.eventmesh.runtime.core.consumergroup.ProducerGroupConf; + +import java.util.concurrent.ConcurrentHashMap; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ProducerManager { + + private final AbstractRemotingServer eventMeshServer; + + /** + * key: group name + */ + private final ConcurrentHashMap producerTable = new ConcurrentHashMap<>(); + + public ProducerManager(AbstractRemotingServer eventMeshServer) { + this.eventMeshServer = eventMeshServer; + } + + public void init() throws Exception { + log.info("producerManager inited......"); + } + + public void start() throws Exception { + log.info("producerManager started......"); + } + + public EventMeshProducer getEventMeshProducer(String producerGroup) throws Exception { + EventMeshProducer eventMeshProducer; + 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.isStarted()) { + eventMeshProducer.start(); + } + + return eventMeshProducer; + } + + public EventMeshProducer getEventMeshProducer(String producerGroup, String token) throws Exception { + EventMeshProducer eventMeshProducer; + if (!producerTable.containsKey(producerGroup)) { + synchronized (producerTable) { + if (!producerTable.containsKey(producerGroup)) { + ProducerGroupConf producerGroupConfig = new ProducerGroupConf(producerGroup, token); + eventMeshProducer = createEventMeshProducer(producerGroupConfig); + eventMeshProducer.start(); + } + } + } + + eventMeshProducer = producerTable.get(producerGroup); + + if (!eventMeshProducer.isStarted()) { + 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(eventMeshServer.getConfiguration(), producerGroupConfig); + producerTable.put(producerGroupConfig.getGroupName(), eventMeshProducer); + return eventMeshProducer; + } + + public void shutdown() { + for (EventMeshProducer eventMeshProducer : producerTable.values()) { + try { + eventMeshProducer.shutdown(); + } catch (Exception ex) { + log.error("shutdown eventMeshProducer[{}] err", eventMeshProducer, ex); + } + } + log.info("producerManager shutdown......"); + } + + public AbstractRemotingServer getEventMeshServer() { + return eventMeshServer; + } + + public ConcurrentHashMap getProducerTable() { + return producerTable; + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/producer/SendMessageContext.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/producer/SendMessageContext.java new file mode 100644 index 0000000000..0de970f701 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/producer/SendMessageContext.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.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.AbstractRemotingServer; +import org.apache.eventmesh.runtime.core.protocol.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 final Logger logger = LoggerFactory.getLogger("retry"); + + private CloudEvent event; + + private String bizSeqNo; + + private EventMeshProducer eventMeshProducer; + + private long createTime = System.currentTimeMillis(); + + public AbstractRemotingServer eventMeshServer; + + public SendMessageContext(String bizSeqNo, CloudEvent event, EventMeshProducer eventMeshProducer, + AbstractRemotingServer eventMeshServer) { + this.bizSeqNo = bizSeqNo; + this.event = event; + this.eventMeshProducer = eventMeshProducer; + this.eventMeshServer = eventMeshServer; + } + + 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_INCLUDE_MILLISECONDS)) + .append(",createTime=") + .append(DateFormatUtils.format(createTime, Constants.DATE_FORMAT_INCLUDE_MILLISECONDS)).append("}"); + return sb.toString(); + } + + public void retry() throws Exception { + if (eventMeshProducer == null) { + logger.error("Exception happends during retry. EventMeshProducer is null."); + return; + } + + if (retryTimes > 0) { // retry once + logger.error("Exception happends during retry. The retryTimes > 0."); + return; + } + + retryTimes++; + eventMeshProducer.send(this, new SendCallback() { + + @Override + public void onSuccess(SendResult sendResult) { + } + + @Override + public void onException(OnExceptionContext context) { + logger.warn("", context.getException()); + } + }); + } + + @Override + public void doRun() throws Exception { + retry(); + } +} 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 index 2622f37c08..fdde4aeb6c 100644 --- 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 @@ -24,7 +24,7 @@ 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.boot.TCPThreadPoolGroup; 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; @@ -35,17 +35,15 @@ import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; -import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; - import lombok.extern.slf4j.Slf4j; @Slf4j public class EventMeshTcp2Client { - public static InetSocketAddress serverGoodby2Client(EventMeshTCPServer eventMeshTCPServer, + public static InetSocketAddress serverGoodby2Client(TCPThreadPoolGroup tcpThreadPoolGroup, Session session, ClientSessionGroupMapping mapping) { log.info("serverGoodby2Client client[{}]", session.getClient()); @@ -55,16 +53,13 @@ public static InetSocketAddress serverGoodby2Client(EventMeshTCPServer eventMesh 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); - } + tcpThreadPoolGroup.getScheduler().submit(() -> { + long taskExecuteTime = System.currentTimeMillis(); + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); }); InetSocketAddress address = (InetSocketAddress) session.getContext().channel().remoteAddress(); - closeSessionIfTimeout(eventMeshTCPServer, session, mapping); + closeSessionIfTimeout(tcpThreadPoolGroup, session, mapping); return address; } catch (Exception e) { log.error("exception occur while serverGoodby2Client", e); @@ -72,22 +67,19 @@ public void run() { } } - public static InetSocketAddress goodBye2Client(EventMeshTCPServer eventMeshTCPServer, Session session, + public static InetSocketAddress goodBye2Client(TCPThreadPoolGroup tcpThreadPoolGroup, 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); - } + tcpThreadPoolGroup.getScheduler().schedule(() -> { + long taskExecuteTime = System.currentTimeMillis(); + Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session); }, 1 * 1000, TimeUnit.MILLISECONDS); - closeSessionIfTimeout(eventMeshTCPServer, session, mapping); + closeSessionIfTimeout(tcpThreadPoolGroup, session, mapping); return session.getRemoteAddress(); } catch (Exception e) { @@ -102,20 +94,17 @@ public static void goodBye2Client(ChannelHandlerContext ctx, String errMsg, Clie Package pkg = new Package(new Header(SERVER_GOODBYE_REQUEST, OPStatus.FAIL.getCode(), errMsg, null)); eventMeshTcpMonitor.getTcpSummaryMetrics().getEventMesh2clientMsgNum().incrementAndGet(); log.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) { - log.warn("close session failed!", e); - } + ctx.writeAndFlush(pkg).addListener((ChannelFutureListener) future -> { + Utils.logSucceedMessageFlow(pkg, null, startTime, startTime); + try { + mapping.closeSession(ctx); + } catch (Exception e) { + log.warn("close session failed!", e); } }); } - public static String redirectClient2NewEventMesh(EventMeshTCPServer eventMeshTCPServer, String newEventMeshIp, + public static String redirectClient2NewEventMesh(TCPThreadPoolGroup tcpThreadPoolGroup, String newEventMeshIp, int port, Session session, ClientSessionGroupMapping mapping) { log.info("begin to gracefully redirect Client {}, newIPPort[{}]", session.getClient(), newEventMeshIp + ":" + port); @@ -125,14 +114,11 @@ public static String redirectClient2NewEventMesh(EventMeshTCPServer eventMeshTCP 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); - } + tcpThreadPoolGroup.getScheduler().schedule(() -> { + long taskExecuteTime = System.currentTimeMillis(); + Utils.writeAndFlush(pkg, startTime, taskExecuteTime, session.getContext(), session); }, 5 * 1000, TimeUnit.MILLISECONDS); - closeSessionIfTimeout(eventMeshTCPServer, session, mapping); + closeSessionIfTimeout(tcpThreadPoolGroup, session, mapping); return session.getRemoteAddress() + "--->" + newEventMeshIp + ":" + port; } catch (Exception e) { log.error("exception occur while redirectClient2NewEventMesh", e); @@ -140,19 +126,16 @@ public void run() { } } - public static void closeSessionIfTimeout(EventMeshTCPServer eventMeshTCPServer, Session session, + public static void closeSessionIfTimeout(TCPThreadPoolGroup tcpThreadPoolGroup, Session session, ClientSessionGroupMapping mapping) { - eventMeshTCPServer.getScheduler().schedule(new Runnable() { - @Override - public void run() { - try { - if (session.getSessionState() != SessionState.CLOSED) { - mapping.closeSession(session.getContext()); - log.info("closeSessionIfTimeout success, session[{}]", session.getClient()); - } - } catch (Exception e) { - log.error("close session failed", e); + tcpThreadPoolGroup.getScheduler().schedule(() -> { + try { + if (session.getSessionState() != SessionState.CLOSED) { + mapping.closeSession(session.getContext()); + log.info("closeSessionIfTimeout success, session[{}]", session.getClient()); } + } catch (Exception e) { + log.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 deleted file mode 100644 index f6542baaae..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpConnectionHandler.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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 io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandler.Sharable; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.timeout.IdleState; -import io.netty.handler.timeout.IdleStateEvent; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Sharable -public class EventMeshTcpConnectionHandler extends ChannelDuplexHandler { - - private final AtomicInteger connections = new AtomicInteger(0); - - 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()); - log.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()); - log.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()); - log.info("client|tcp|channelActive|remoteAddress={}|msg={}", remoteAddress, ""); - - if (connections.incrementAndGet() > eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpClientMaxNum()) { - log.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()); - log.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()); - log.info("client|tcp|userEventTriggered|remoteAddress={}|msg={}", remoteAddress, evt.getClass().getName()); - eventMeshTCPServer.getClientSessionGroupMapping().closeSession(ctx); - } - } - - ctx.fireUserEventTriggered(evt); - } - - public int getConnectionCount() { - return this.connections.get(); - } -} 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 deleted file mode 100644 index a96e5ef37c..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpExceptionHandler.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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 io.netty.channel.ChannelDuplexHandler; -import io.netty.channel.ChannelHandlerContext; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class EventMeshTcpExceptionHandler extends ChannelDuplexHandler { - - 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(); - log.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 deleted file mode 100644 index 9d639711f6..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/EventMeshTcpMessageDispatcher.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.util.EventMeshUtil; -import org.apache.eventmesh.runtime.util.TraceUtils; -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; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class EventMeshTcpMessageDispatcher extends SimpleChannelInboundHandler { - - private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.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().getEventMeshServerIp()); - 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 (Command.RECOMMEND_REQUEST == cmd) { - if (MESSAGE_LOGGER.isInfoEnabled()) { - MESSAGE_LOGGER.info("pkg|c2eventMesh|cmd={}|pkg={}", cmd, pkg); - } - task = new RecommendTask(pkg, ctx, startTime, eventMeshTCPServer); - eventMeshTCPServer.getTaskHandleExecutorService().submit(task); - return; - } - - if (Command.HELLO_REQUEST == cmd) { - if (MESSAGE_LOGGER.isInfoEnabled()) { - MESSAGE_LOGGER.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) { - if (MESSAGE_LOGGER.isInfoEnabled()) { - MESSAGE_LOGGER.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) { - log.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().isEventMeshServerTraceEnable() - && 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) { - log.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) { - if (MESSAGE_LOGGER.isInfoEnabled()) { - MESSAGE_LOGGER.info("pkg|c2eventMesh|cmd={}|Msg={}|user={}", cmd, - EventMeshUtil.printMqMessage((EventMeshMessage) pkg.getBody()), - eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx).getClient()); - } - } else { - if (MESSAGE_LOGGER.isInfoEnabled()) { - MESSAGE_LOGGER.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) { - log.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) { - log.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 index ac45ca6cb3..f5a6f748e4 100644 --- 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 @@ -36,7 +36,7 @@ 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.retry.TcpRetryer; 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.util.EventMeshUtil; @@ -49,9 +49,11 @@ import java.nio.charset.StandardCharsets; 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.Properties; import java.util.Set; @@ -66,9 +68,9 @@ import com.google.common.base.Preconditions; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; - @Slf4j public class ClientGroupWrapper { @@ -80,7 +82,7 @@ public class ClientGroupWrapper { private final EventMeshTCPServer eventMeshTCPServer; - private EventMeshTcpRetryer eventMeshTcpRetryer; + private TcpRetryer tcpRetryer; private EventMeshTcpMonitor eventMeshTcpMonitor; @@ -88,29 +90,36 @@ public class ClientGroupWrapper { private final ReadWriteLock groupLock = new ReentrantReadWriteLock(); - public Set groupConsumerSessions = new HashSet(); + @Getter + private final Set groupConsumerSessions = new HashSet(); + + @Getter + private final Set groupProducerSessions = new HashSet(); - public Set groupProducerSessions = new HashSet(); + @Getter + private final AtomicBoolean started4Persistent = new AtomicBoolean(Boolean.FALSE); - public AtomicBoolean started4Persistent = new AtomicBoolean(Boolean.FALSE); + @Getter + private final AtomicBoolean started4Broadcast = new AtomicBoolean(Boolean.FALSE); - public AtomicBoolean started4Broadcast = new AtomicBoolean(Boolean.FALSE); + @Getter + private final AtomicBoolean inited4Persistent = new AtomicBoolean(Boolean.FALSE); - public AtomicBoolean inited4Persistent = new AtomicBoolean(Boolean.FALSE); + @Getter + private final AtomicBoolean inited4Broadcast = new AtomicBoolean(Boolean.FALSE); - public AtomicBoolean inited4Broadcast = new AtomicBoolean(Boolean.FALSE); + @Getter + private final AtomicBoolean producerStarted = new AtomicBoolean(Boolean.FALSE); private MQConsumerWrapper persistentMsgConsumer; private MQConsumerWrapper broadCastMsgConsumer; - private final ConcurrentHashMap> topic2sessionInGroupMapping = - new ConcurrentHashMap>(); + private final ConcurrentHashMap> topic2sessionInGroupMapping = + new ConcurrentHashMap>(); private final ConcurrentHashMap subscriptions = new ConcurrentHashMap<>(); - public AtomicBoolean producerStarted = new AtomicBoolean(Boolean.FALSE); - private final MQProducerWrapper mqProducerWrapper; public ClientGroupWrapper(String sysId, String group, @@ -120,7 +129,7 @@ public ClientGroupWrapper(String sysId, String group, this.group = group; this.eventMeshTCPServer = eventMeshTCPServer; this.eventMeshTCPConfiguration = eventMeshTCPServer.getEventMeshTCPConfiguration(); - this.eventMeshTcpRetryer = eventMeshTCPServer.getEventMeshTcpRetryer(); + this.tcpRetryer = eventMeshTCPServer.getTcpRetryer(); this.eventMeshTcpMonitor = Preconditions.checkNotNull(eventMeshTCPServer.getEventMeshTcpMonitor()); this.downstreamDispatchStrategy = downstreamDispatchStrategy; @@ -129,7 +138,7 @@ public ClientGroupWrapper(String sysId, String group, this.mqProducerWrapper = new MQProducerWrapper(eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshStoragePluginType()); } - public ConcurrentHashMap> getTopic2sessionInGroupMapping() { + public ConcurrentHashMap> getTopic2sessionInGroupMapping() { return topic2sessionInGroupMapping; } @@ -139,6 +148,9 @@ public boolean hasSubscription(String topic) { this.groupLock.readLock().lockInterruptibly(); has = topic2sessionInGroupMapping.containsKey(topic); } catch (Exception e) { + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } log.error("hasSubscription error! topic[{}]", topic); } finally { this.groupLock.readLock().unlock(); @@ -161,9 +173,9 @@ public void request(UpStreamMsgContext upStreamMsgContext, RequestReplyCallback public boolean reply(UpStreamMsgContext upStreamMsgContext) throws Exception { mqProducerWrapper.reply(upStreamMsgContext.getEvent(), new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { - } @Override @@ -185,39 +197,37 @@ public MQProducerWrapper getMqProducerWrapper() { public boolean addSubscription(SubscriptionItem subscriptionItem, Session session) throws Exception { if (subscriptionItem == null) { - log.error("addSubscription param error,subscriptionItem is null, session:{}", session); + log.error("addSubscription param error, subscriptionItem is null, session:{}", session); return false; } String topic = subscriptionItem.getTopic(); if (session == null || !StringUtils.equalsIgnoreCase(group, EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { - log.error("addSubscription param error,topic:{},session:{}", topic, session); + log.error("addSubscription param error, topic:{}, session:{}", topic, session); return false; } - boolean r; + boolean r = false; try { this.groupLock.writeLock().lockInterruptibly(); if (!topic2sessionInGroupMapping.containsKey(topic)) { - Set sessions = new HashSet(); + Map sessions = new HashMap<>(); topic2sessionInGroupMapping.put(topic, sessions); } - r = topic2sessionInGroupMapping.get(topic).add(session); - if (r) { - - if (log.isInfoEnabled()) { - log.info("addSubscription success, group:{} topic:{} client:{}", group, - topic, session.getClient()); - } + Session s = topic2sessionInGroupMapping.get(topic).putIfAbsent(session.getSessionId(), session); + if (s == null) { + log.info("Cache session success, group:{} topic:{} client:{} sessionId:{}", + group, topic, session.getClient(), session.getSessionId()); } else { - if (log.isWarnEnabled()) { - log.warn("addSubscription fail, group:{} topic:{} client:{}", group, topic, - session.getClient()); - } + log.warn("Session already exists in topic2sessionInGroupMapping. group:{} topic:{} client:{} sessionId:{}", + group, topic, session.getClient(), session.getSessionId()); } subscriptions.putIfAbsent(topic, subscriptionItem); } catch (Exception e) { + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } log.error("addSubscription error! topic:{} client:{}", topic, session.getClient(), e); throw new Exception("addSubscription fail"); } finally { @@ -232,10 +242,8 @@ public boolean removeSubscription(SubscriptionItem subscriptionItem, Session ses return false; } String topic = subscriptionItem.getTopic(); - if (session == null - || !StringUtils.equalsIgnoreCase(group, - EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { - log.error("removeSubscription param error,topic:{},session:{}", topic, session); + if (session == null || !StringUtils.equalsIgnoreCase(group, EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + log.error("removeSubscription param error, topic:{}, session:{}", topic, session); return false; } @@ -243,20 +251,12 @@ public boolean removeSubscription(SubscriptionItem subscriptionItem, Session ses try { this.groupLock.writeLock().lockInterruptibly(); if (topic2sessionInGroupMapping.containsKey(topic)) { - r = topic2sessionInGroupMapping.get(topic).remove(session); - if (r) { - - if (log.isInfoEnabled()) { - log.info( - "removeSubscription remove session success, group:{} topic:{} client:{}", - group, topic, session.getClient()); - } + if (topic2sessionInGroupMapping.get(topic).remove(session.getSessionId()) != null) { + log.info("removeSubscription remove session success, group:{} topic:{} client:{}", + group, topic, session.getClient()); } else { - if (log.isWarnEnabled()) { - log.warn( - "removeSubscription remove session failed, group:{} topic:{} client:{}", - group, topic, session.getClient()); - } + log.warn("Not found session in cache, group:{} topic:{} client:{} sessionId:{}", + group, topic, session.getClient(), session.getSessionId()); } } if (CollectionUtils.size(topic2sessionInGroupMapping.get(topic)) == 0) { @@ -267,6 +267,9 @@ public boolean removeSubscription(SubscriptionItem subscriptionItem, Session ses group, topic); } } catch (Exception e) { + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } log.error("removeSubscription error! topic:{} client:{}", topic, session.getClient(), e); } finally { @@ -286,7 +289,7 @@ public synchronized void startClientGroupProducer() throws Exception { .buildMeshTcpClientID(sysId, EventMeshConstants.PURPOSE_PUB_UPPER_CASE, eventMeshTCPConfiguration.getEventMeshCluster())); - //TODO for defibus + // TODO for defibus keyValue.put(EventMeshConstants.EVENT_MESH_IDC, eventMeshTCPConfiguration.getEventMeshIDC()); mqProducerWrapper.init(keyValue); @@ -313,11 +316,8 @@ public void setGroup(String group) { } public boolean addGroupConsumerSession(Session session) { - if (session == null - || !StringUtils.equalsIgnoreCase(group, - EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { - - log.error("addGroupConsumerSession param error,session:{}", session); + if (session == null || !StringUtils.equalsIgnoreCase(group, EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + log.error("addGroupConsumerSession param error, session:{}", session); return false; } @@ -326,15 +326,13 @@ public boolean addGroupConsumerSession(Session session) { this.groupLock.writeLock().lockInterruptibly(); r = groupConsumerSessions.add(session); if (r) { - - if (log.isInfoEnabled()) { - log.info("addGroupConsumerSession success, group:{} client:{}", group, - session.getClient()); - } + log.info("addGroupConsumerSession success, group:{} client:{}", group, session.getClient()); } } catch (Exception e) { - log.error("addGroupConsumerSession error! group:{} client:{}", group, - session.getClient(), e); + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + log.error("addGroupConsumerSession error! group:{} client:{}", group, session.getClient(), e); } finally { this.groupLock.writeLock().unlock(); } @@ -342,11 +340,8 @@ public boolean addGroupConsumerSession(Session session) { } public boolean addGroupProducerSession(Session session) { - if (session == null - || !StringUtils.equalsIgnoreCase(group, - EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { - - log.error("addGroupProducerSession param error,session:{}", session); + if (session == null || !StringUtils.equalsIgnoreCase(group, EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + log.error("addGroupProducerSession param error, session:{}", session); return false; } @@ -356,12 +351,13 @@ public boolean addGroupProducerSession(Session session) { r = groupProducerSessions.add(session); if (r) { - log.info("addGroupProducerSession success, group:{} client:{}", group, - session.getClient()); + log.info("addGroupProducerSession success, group:{} client:{}", group, session.getClient()); } } catch (Exception e) { - log.error("addGroupProducerSession error! group:{} client:{}", group, - session.getClient(), e); + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + log.error("addGroupProducerSession error! group:{} client:{}", group, session.getClient(), e); } finally { this.groupLock.writeLock().unlock(); } @@ -369,11 +365,8 @@ public boolean addGroupProducerSession(Session session) { } public boolean removeGroupConsumerSession(Session session) { - if (session == null - || !StringUtils.equalsIgnoreCase(group, - EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { - - log.error("removeGroupConsumerSession param error,session:{}", session); + if (session == null || !StringUtils.equalsIgnoreCase(group, EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + log.error("removeGroupConsumerSession param error, session:{}", session); return false; } @@ -382,15 +375,13 @@ public boolean removeGroupConsumerSession(Session session) { this.groupLock.writeLock().lockInterruptibly(); r = groupConsumerSessions.remove(session); if (r) { - - if (log.isInfoEnabled()) { - log.info("removeGroupConsumerSession success, group:{} client:{}", group, - session.getClient()); - } + log.info("removeGroupConsumerSession success, group:{} client:{}", group, session.getClient()); } } catch (Exception e) { - log.error("removeGroupConsumerSession error! group:{} client:{}", group, - session.getClient(), e); + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + log.error("removeGroupConsumerSession error! group:{} client:{}", group, session.getClient(), e); } finally { this.groupLock.writeLock().unlock(); } @@ -398,10 +389,8 @@ public boolean removeGroupConsumerSession(Session session) { } public boolean removeGroupProducerSession(Session session) { - if (session == null - || !StringUtils.equalsIgnoreCase(group, - EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { - log.error("removeGroupProducerSession param error,session:{}", session); + if (session == null || !StringUtils.equalsIgnoreCase(group, EventMeshUtil.buildClientGroup(session.getClient().getGroup()))) { + log.error("removeGroupProducerSession param error, session:{}", session); return false; } @@ -411,12 +400,13 @@ public boolean removeGroupProducerSession(Session session) { r = groupProducerSessions.remove(session); if (r) { - log.info("removeGroupProducerSession success, group:{} client:{}", group, - session.getClient()); + log.info("removeGroupProducerSession success, group:{} client:{}", group, session.getClient()); } } catch (Exception e) { - log.error("removeGroupProducerSession error! group:{} client:{}", group, - session.getClient(), e); + if (e instanceof InterruptedException) { + Thread.currentThread().interrupt(); + } + log.error("removeGroupProducerSession error! group:{} client:{}", group, session.getClient(), e); } finally { this.groupLock.writeLock().unlock(); } @@ -454,7 +444,8 @@ public synchronized void initClientGroupPersistentConsumer() throws Exception { .withExtension(EventMeshConstants.REQ_MQ2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) .withExtension(EventMeshConstants.REQ_RECEIVE_EVENTMESH_IP, - eventMeshTCPConfiguration.getEventMeshServerIp()).build(); + eventMeshTCPConfiguration.getEventMeshServerIp()) + .build(); String topic = event.getSubject(); EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = @@ -493,7 +484,8 @@ public synchronized void initClientGroupPersistentConsumer() throws Exception { .withExtension(EventMeshConstants.EVENTMESH_SEND_BACK_TIMES, sendBackTimes.toString()) .withExtension(EventMeshConstants.EVENTMESH_SEND_BACK_IP, - eventMeshTCPConfiguration.getEventMeshServerIp()).build(); + eventMeshTCPConfiguration.getEventMeshServerIp()) + .build(); sendMsgBackToBroker(event, bizSeqNo); } } catch (Exception e) { @@ -509,7 +501,7 @@ public synchronized void initClientGroupPersistentConsumer() throws Exception { new DownStreamMsgContext(event, session, persistentMsgConsumer, eventMeshAsyncConsumeContext.getAbstractContext(), false, subscriptionItem); - //msg put in eventmesh,waiting client ack + // msg put in eventmesh,waiting client ack session.getPusher().unAckMsg(downStreamMsgContext.seq, downStreamMsgContext); session.downstreamMsg(downStreamMsgContext); eventMeshAsyncConsumeContext.commit(EventMeshAction.ManualAck); @@ -520,9 +512,7 @@ public synchronized void initClientGroupPersistentConsumer() throws Exception { persistentMsgConsumer.registerEventListener(listener); inited4Persistent.compareAndSet(false, true); - if (log.isInfoEnabled()) { - log.info("init persistentMsgConsumer success, group:{}", group); - } + log.info("init persistentMsgConsumer success, group:{}", group); } public synchronized void startClientGroupPersistentConsumer() throws Exception { @@ -531,9 +521,7 @@ public synchronized void startClientGroupPersistentConsumer() throws Exception { } persistentMsgConsumer.start(); started4Persistent.compareAndSet(false, true); - if (log.isInfoEnabled()) { - log.info("starting persistentMsgConsumer success, group:{}", group); - } + log.info("starting persistentMsgConsumer success, group:{}", group); } public synchronized void initClientGroupBroadcastConsumer() throws Exception { @@ -564,15 +552,14 @@ public synchronized void initClientGroupBroadcastConsumer() throws Exception { .withExtension(EventMeshConstants.REQ_MQ2EVENTMESH_TIMESTAMP, String.valueOf(System.currentTimeMillis())) .withExtension(EventMeshConstants.REQ_RECEIVE_EVENTMESH_IP, - eventMeshTCPConfiguration.getEventMeshServerIp()).build(); + eventMeshTCPConfiguration.getEventMeshServerIp()) + .build(); String topic = event.getSubject(); EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = (EventMeshAsyncConsumeContext) context; if (CollectionUtils.isEmpty(groupConsumerSessions)) { - if (log.isWarnEnabled()) { - log.warn("found no session to downstream broadcast msg"); - } + log.warn("found no session to downstream broadcast msg"); eventMeshAsyncConsumeContext.commit(EventMeshAction.CommitMessage); return; } @@ -589,19 +576,16 @@ public synchronized void initClientGroupBroadcastConsumer() throws Exception { Session session = sessionsItr.next(); if (!session.isAvailable(topic)) { - if (log.isWarnEnabled()) { - log.warn("downstream broadcast msg,session is not available,client:{}", - session.getClient()); - } + log.warn("downstream broadcast msg, session is not available, client:{}", session.getClient()); continue; } downStreamMsgContext.setSession(session); - //downstream broadcast msg asynchronously - eventMeshTCPServer.getBroadcastMsgDownstreamExecutorService() + // downstream broadcast msg asynchronously + eventMeshTCPServer.getTcpThreadPoolGroup().getBroadcastMsgDownstreamExecutorService() .submit(() -> { - //msg put in eventmesh,waiting client ack + // msg put in eventmesh,waiting client ack session.getPusher().unAckMsg(downStreamMsgContext.seq, downStreamMsgContext); session.downstreamMsg(downStreamMsgContext); }); @@ -615,9 +599,7 @@ public synchronized void initClientGroupBroadcastConsumer() throws Exception { broadCastMsgConsumer.registerEventListener(listener); inited4Broadcast.compareAndSet(false, true); - if (log.isInfoEnabled()) { - log.info("init broadCastMsgConsumer success, group:{}", group); - } + log.info("init broadCastMsgConsumer success, group:{}", group); } public synchronized void startClientGroupBroadcastConsumer() throws Exception { @@ -648,9 +630,7 @@ public void unsubscribe(SubscriptionItem subscriptionItem) throws Exception { public synchronized void shutdownBroadCastConsumer() throws Exception { if (started4Broadcast.get()) { broadCastMsgConsumer.shutdown(); - if (log.isInfoEnabled()) { - log.info("broadcast consumer group:{} shutdown...", group); - } + log.info("broadcast consumer group:{} shutdown...", group); } started4Broadcast.compareAndSet(true, false); inited4Broadcast.compareAndSet(true, false); @@ -661,23 +641,13 @@ public synchronized void shutdownPersistentConsumer() throws Exception { if (started4Persistent.get()) { persistentMsgConsumer.shutdown(); - if (log.isInfoEnabled()) { - log.info("persistent consumer group:{} shutdown...", group); - } + log.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; } @@ -686,12 +656,12 @@ public void setEventMeshTCPConfiguration(EventMeshTCPConfiguration eventMeshTCPC this.eventMeshTCPConfiguration = eventMeshTCPConfiguration; } - public EventMeshTcpRetryer getEventMeshTcpRetryer() { - return eventMeshTcpRetryer; + public TcpRetryer getTcpRetryer() { + return tcpRetryer; } - public void setEventMeshTcpRetryer(EventMeshTcpRetryer eventMeshTcpRetryer) { - this.eventMeshTcpRetryer = eventMeshTcpRetryer; + public void setTcpRetryer(TcpRetryer tcpRetryer) { + this.tcpRetryer = tcpRetryer; } public EventMeshTcpMonitor getEventMeshTcpMonitor() { @@ -722,9 +692,7 @@ private String pushMsgToEventMesh(CloudEvent msg, String ip, int port) throws Ex HttpTinyClient.HttpResult result = null; try { - if (log.isInfoEnabled()) { - log.info("pushMsgToEventMesh,targetUrl:{},msg:{}", targetUrl, msg); - } + log.info("pushMsgToEventMesh,targetUrl:{},msg:{}", targetUrl, msg); List paramValues = new ArrayList(); paramValues.add(EventMeshConstants.MANAGE_MSG); paramValues.add(JsonUtils.toJSONString(msg)); @@ -758,39 +726,29 @@ public MQConsumerWrapper getPersistentMsgConsumer() { private void sendMsgBackToBroker(CloudEvent event, String bizSeqNo) throws Exception { try { String topic = event.getSubject(); - if (log.isWarnEnabled()) { - log.warn("send msg back to broker, bizSeqno:{}, topic:{}", bizSeqNo, topic); - } + log.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) { - - if (log.isInfoEnabled()) { - log.info( - "group:{} consume fail, sendMessageBack success, bizSeqno:{}, " - + "topic:{}", group, bizSeqNo, topic); - } + log.info("group:{} consume fail, sendMessageBack success, bizSeqno:{}, topic:{}", + group, bizSeqNo, topic); } @Override public void onException(OnExceptionContext context) { - if (log.isWarnEnabled()) { - log.warn( - "group:{} consume fail, sendMessageBack fail, bizSeqno:{}," - + " topic:{}", group, bizSeqNo, topic); - } + log.warn("group:{} consume fail, sendMessageBack fail, bizSeqno:{}, topic:{}", + group, bizSeqNo, topic); } }); eventMeshTcpMonitor.getTcpSummaryMetrics().getEventMesh2mqMsgNum().incrementAndGet(); } catch (Exception e) { - if (log.isWarnEnabled()) { - log.warn("try send msg back to broker failed"); - } + log.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 index a0c0880088..94086b82d3 100644 --- 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 @@ -17,12 +17,16 @@ package org.apache.eventmesh.runtime.core.protocol.tcp.client.group; +import org.apache.eventmesh.api.meta.config.EventMeshMetaConfig; 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.JsonUtils; 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.consumergroup.ConsumerGroupMetadata; +import org.apache.eventmesh.runtime.core.consumergroup.ConsumerGroupTopicMetadata; 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; @@ -38,8 +42,10 @@ import java.lang.ref.WeakReference; import java.net.InetSocketAddress; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -58,10 +64,16 @@ public class ClientSessionGroupMapping { private final ConcurrentHashMap sessionTable = new ConcurrentHashMap<>(); - private final ConcurrentHashMap clientGroupMap = + /** + * key: subsystem eg . 5109 or 5109-1A0 + */ + private final ConcurrentHashMap clientGroupMap = new ConcurrentHashMap(); - private final ConcurrentHashMap lockMap = + /** + * key: subsystem eg . 5109 or 5109-1A0 + */ + private final ConcurrentHashMap lockMap = new ConcurrentHashMap(); private EventMeshTCPServer eventMeshTCPServer; @@ -131,7 +143,7 @@ public synchronized void closeSession(ChannelHandlerContext ctx) throws Exceptio closeSession(session); - //remove session from sessionTable + // remove session from sessionTable sessionTable.remove(addr); SESSION_LOGGER.info("session|close|succeed|user={}", session.getClient()); @@ -144,7 +156,7 @@ private void closeSession(Session session) throws Exception { return; } - //session must be synchronized to avoid SessionState be confound, for example adding subscribe when session closing + // session must be synchronized to avoid SessionState be confound, for example adding subscribe when session closing synchronized (session) { if (SessionState.CLOSED == session.getSessionState()) { @@ -154,12 +166,20 @@ private void closeSession(Session session) throws Exception { 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 { - log.error("client purpose config is error:{}", session.getClient().getPurpose()); + final String clientGroup = session.getClient().getGroup(); + if (!lockMap.containsKey(clientGroup)) { + lockMap.putIfAbsent(clientGroup, new Object()); + } + synchronized (lockMap.get(clientGroup)) { + if (EventMeshConstants.PURPOSE_SUB.equals(session.getClient().getPurpose())) { + cleanClientGroupWrapperByCloseSub(session); + } else if (EventMeshConstants.PURPOSE_PUB.equals( + session.getClient().getPurpose())) { + cleanClientGroupWrapperByClosePub(session); + } else { + log.error("client purpose config is error:{}", + session.getClient().getPurpose()); + } } if (session.getContext() != null) { @@ -209,7 +229,7 @@ private void initClientGroupWrapper(UserAgent user, Session session) throws Exce } private void startClientGroupProducer(ClientGroupWrapper cgw, Session session) throws Exception { - if (!cgw.producerStarted.get()) { + if (!cgw.getProducerStarted().get()) { cgw.startClientGroupProducer(); } boolean flag = cgw.addGroupProducerSession(session); @@ -220,15 +240,15 @@ private void startClientGroupProducer(ClientGroupWrapper cgw, Session session) t } private void initClientGroupConsumser(ClientGroupWrapper cgw) throws Exception { - if (!cgw.producerStarted.get()) { + if (!cgw.getProducerStarted().get()) { cgw.startClientGroupProducer(); } - if (!cgw.inited4Broadcast.get()) { + if (!cgw.getInited4Broadcast().get()) { cgw.initClientGroupBroadcastConsumer(); } - if (!cgw.inited4Persistent.get()) { + if (!cgw.getInited4Persistent().get()) { cgw.initClientGroupPersistentConsumer(); } } @@ -247,10 +267,10 @@ private void startClientGroupConsumer(Session session) throws Exception { throw new Exception("addGroupConsumerSession fail"); } - if (cgw.inited4Persistent.get() && !cgw.started4Persistent.get()) { + if (cgw.getInited4Persistent().get() && !cgw.getStarted4Persistent().get()) { cgw.startClientGroupPersistentConsumer(); } - if (cgw.inited4Broadcast.get() && !cgw.started4Broadcast.get()) { + if (cgw.getInited4Broadcast().get() && !cgw.getStarted4Broadcast().get()) { cgw.startClientGroupBroadcastConsumer(); } session.setSessionState(SessionState.RUNNING); @@ -292,7 +312,8 @@ private void cleanSubscriptionInSession(Session session) throws Exception { * @param session */ private void handleUnackMsgsInSession(Session session) { - ConcurrentHashMap unAckMsg = session.getPusher().getUnAckMsg(); + // key: seq + ConcurrentHashMap unAckMsg = session.getPusher().getUnAckMsg(); ClientGroupWrapper clientGroupWrapper = Objects.requireNonNull(session.getClientGroupWrapper().get()); if (unAckMsg.size() > 0 && !clientGroupWrapper.getGroupConsumerSessions().isEmpty()) { for (Map.Entry entry : unAckMsg.entrySet()) { @@ -306,7 +327,7 @@ private void handleUnackMsgsInSession(Session session) { Session reChooseSession = clientGroupWrapper.getDownstreamDispatchStrategy() .select(clientGroupWrapper.getGroup(), downStreamMsgContext.event.getSubject(), - clientGroupWrapper.groupConsumerSessions); + clientGroupWrapper.getGroupConsumerSessions()); if (reChooseSession != null) { downStreamMsgContext.setSession(reChooseSession); reChooseSession.getPusher().unAckMsg(downStreamMsgContext.seq, downStreamMsgContext); @@ -340,32 +361,29 @@ private void cleanClientGroupWrapperCommon(ClientGroupWrapper clientGroupWrapper } private void shutdownClientGroupConsumer(ClientGroupWrapper clientGroupWrapper) throws Exception { - if (clientGroupWrapper.started4Broadcast.get()) { + if (clientGroupWrapper.getStarted4Broadcast().get()) { clientGroupWrapper.shutdownBroadCastConsumer(); } - if (clientGroupWrapper.started4Persistent.get()) { + if (clientGroupWrapper.getStarted4Persistent().get()) { clientGroupWrapper.shutdownPersistentConsumer(); } } - private void shutdownClientGroupProducer(ClientGroupWrapper clientGroupWrapper) throws Exception { - if (clientGroupWrapper.producerStarted.get()) { + if (clientGroupWrapper.getProducerStarted().get()) { clientGroupWrapper.shutdownProducer(); } } private void initSessionCleaner() { - eventMeshTCPServer.getScheduler().scheduleAtFixedRate( + eventMeshTCPServer.getTcpThreadPoolGroup().getScheduler().scheduleAtFixedRate( () -> { for (Session tmp : sessionTable.values()) { - if (System.currentTimeMillis() - tmp.getLastHeartbeatTime() - > eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpSessionExpiredInMills()) { + long interval = System.currentTimeMillis() - tmp.getLastHeartbeatTime(); + if (interval > eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpSessionExpiredInMills()) { try { - if (log.isWarnEnabled()) { - log.warn("clean expired session,client:{}", tmp.getClient()); - } + log.warn("clean expired session,client:{}", tmp.getClient()); closeSession(tmp.getContext()); } catch (Exception e) { log.error("say goodbye to session error! {}", tmp, e); @@ -376,10 +394,10 @@ private void initSessionCleaner() { } private void initDownStreamMsgContextCleaner() { - eventMeshTCPServer.getScheduler().scheduleAtFixedRate( + eventMeshTCPServer.getTcpThreadPoolGroup().getScheduler().scheduleAtFixedRate( () -> { - //scan non-broadcast msg + // scan non-broadcast msg for (Session tmp : sessionTable.values()) { for (Map.Entry entry : tmp.getPusher().getUnAckMsg().entrySet()) { String seqKey = entry.getKey(); @@ -396,7 +414,6 @@ private void initDownStreamMsgContextCleaner() { }, 1000, 5 * 1000, TimeUnit.MILLISECONDS); } - public void init() throws Exception { initSessionCleaner(); initDownStreamMsgContextCleaner(); @@ -412,7 +429,7 @@ public void shutdown() throws Exception { for (ClientGroupWrapper clientGroupWrapper : clientGroupMap.values()) { for (Session subSession : clientGroupWrapper.getGroupConsumerSessions()) { try { - EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer, subSession, this); + EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer.getTcpThreadPoolGroup(), subSession, this); } catch (Exception e) { log.error("say goodbye to subSession error! {}", subSession, e); } @@ -420,7 +437,7 @@ public void shutdown() throws Exception { for (Session pubSession : clientGroupWrapper.getGroupProducerSessions()) { try { - EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer, pubSession, this); + EventMeshTcp2Client.serverGoodby2Client(eventMeshTCPServer.getTcpThreadPoolGroup(), pubSession, this); } catch (Exception e) { log.error("say goodbye to pubSession error! {}", pubSession, e); } @@ -434,7 +451,7 @@ public void shutdown() throws Exception { sessionTable.values().parallelStream().forEach(itr -> { try { - EventMeshTcp2Client.serverGoodby2Client(this.eventMeshTCPServer, itr, this); + EventMeshTcp2Client.serverGoodby2Client(this.eventMeshTCPServer.getTcpThreadPoolGroup(), itr, this); } catch (Exception e) { log.error("say goodbye to session error! {}", itr, e); } @@ -482,4 +499,48 @@ public Map> prepareProxyClientDistributionData() { return result; } + + public void updateMetaData() { + if (!eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerMetaStorageEnable()) { + return; + } + try { + Map metadata = new HashMap<>(1 << 4); + + for (Map.Entry clientGroupWrapperMap : this.clientGroupMap.entrySet()) { + String group = clientGroupWrapperMap.getKey(); + ClientGroupWrapper cgw = clientGroupWrapperMap.getValue(); + ConsumerGroupMetadata consumerGroupMetadata = new ConsumerGroupMetadata(); + consumerGroupMetadata.setConsumerGroup(group); + Map consumerGroupTopicMetadataMap = + new HashMap<>(1 << 4); + Map> topic2sessionInGroupMapping = cgw.getTopic2sessionInGroupMapping(); + for (Map.Entry> topicSessionMap : topic2sessionInGroupMapping.entrySet()) { + String topic = topicSessionMap.getKey(); + Map sessionMap = topicSessionMap.getValue(); + + ConsumerGroupTopicMetadata consumerGroupTopicMetadata = new ConsumerGroupTopicMetadata(); + consumerGroupTopicMetadata.setConsumerGroup(group); + consumerGroupTopicMetadata.setTopic(topic); + Set sessionSet = new HashSet<>(); + for (Map.Entry sessionEntry : sessionMap.entrySet()) { + String sessionId = sessionEntry.getKey(); + Session session = sessionEntry.getValue(); + sessionSet.add(session.toString()); + } + consumerGroupTopicMetadata.setUrls(sessionSet); + consumerGroupTopicMetadataMap.put(topic, consumerGroupTopicMetadata); + } + + consumerGroupMetadata.setConsumerGroupTopicMetadataMap(consumerGroupTopicMetadataMap); + metadata.put(group, JsonUtils.toJSONString(consumerGroupMetadata)); + } + metadata.put(EventMeshMetaConfig.EVENT_MESH_PROTO, "tcp"); + + eventMeshTCPServer.getMetaStorage().updateMetaData(metadata); + + } catch (Exception e) { + log.error("update eventmesh metadata error", e); + } + } } 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 index 0fbc634d3a..d795285ea2 100644 --- 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 @@ -17,7 +17,6 @@ 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; 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 index 68561347d7..c466557401 100644 --- 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 @@ -49,10 +49,8 @@ public Session select(final String group, final String topic, final Set if (session.isIsolated()) { isolatedSessions.add(session); - if (log.isInfoEnabled()) { - log.info("session is not available because session is isolated,isolateTime:{},client:{}", - session.getIsolateTime(), session.getClient()); - } + log.info("session is not available because session is isolated,isolateTime:{},client:{}", + session.getIsolateTime(), session.getClient()); continue; } @@ -61,14 +59,10 @@ public Session select(final String group, final String topic, final Set if (CollectionUtils.isEmpty(filtered)) { if (CollectionUtils.isEmpty(isolatedSessions)) { - if (log.isWarnEnabled()) { - log.warn("all sessions can't downstream msg"); - } + log.warn("all sessions can't downstream msg"); return null; } else { - if (log.isWarnEnabled()) { - log.warn("all sessions are isolated,group:{},topic:{}", group, topic); - } + log.warn("all sessions are isolated,group:{},topic:{}", group, topic); filtered.addAll(isolatedSessions); } } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/GoodbyeProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/GoodbyeProcessor.java new file mode 100644 index 0000000000..1cb7c04c85 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/GoodbyeProcessor.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.tcp.client.processor; + +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.acl.Acl; +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.session.Session; +import org.apache.eventmesh.runtime.util.Utils; + +import java.util.Arrays; + +import io.netty.channel.ChannelHandlerContext; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class GoodbyeProcessor implements TcpProcessor { + + private EventMeshTCPServer eventMeshTCPServer; + private final Acl acl; + + public GoodbyeProcessor(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.acl = eventMeshTCPServer.getAcl(); + } + + @Override + public void process(final Package pkg, final ChannelHandlerContext ctx, long startTime) { + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + long taskExecuteTime = System.currentTimeMillis(); + Package msg = new Package(); + try { + if (pkg.getHeader().getCmd() == Command.SERVER_GOODBYE_RESPONSE) { + log.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) { + log.error("GoodbyeTask failed|user={}|errMsg={}", session.getClient(), e); + msg.setHeader(new Header(CLIENT_GOODBYE_RESPONSE, OPStatus.FAIL.getCode(), Arrays.toString(e.getStackTrace()), + pkg.getHeader().getSeq())); + } finally { + this.eventMeshTCPServer.getTcpThreadPoolGroup().getScheduler() + .submit(() -> Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session)); + } + EventMeshTcp2Client + .closeSessionIfTimeout(this.eventMeshTCPServer.getTcpThreadPoolGroup(), session, eventMeshTCPServer.getClientSessionGroupMapping()); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/HeartBeatProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/HeartBeatProcessor.java new file mode 100644 index 0000000000..a4677dc1d0 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/HeartBeatProcessor.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.processor; + +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.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.Utils; + +import java.util.Objects; + +import io.netty.channel.ChannelHandlerContext; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HeartBeatProcessor implements TcpProcessor { + + private EventMeshTCPServer eventMeshTCPServer; + private final Acl acl; + + public HeartBeatProcessor(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.acl = eventMeshTCPServer.getAcl(); + } + + @Override + public void process(final Package pkg, final ChannelHandlerContext ctx, long startTime) { + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + long taskExecuteTime = System.currentTimeMillis(); + Package res = new Package(); + try { + // do acl check in heartbeat + if (eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerSecurityEnable()) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + this.acl.doAclCheckInTcpHeartbeat(remoteAddr, session.getClient(), HEARTBEAT_REQUEST.getValue()); + } + + if (session != null) { + session.notifyHeartbeat(startTime); + } + res.setHeader(new Header(HEARTBEAT_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), + pkg.getHeader().getSeq())); + } catch (Exception e) { + log.error("HeartBeatTask failed|user={}|errMsg={}", Objects.requireNonNull(session).getClient(), e); + res.setHeader(new Header(HEARTBEAT_RESPONSE, OPStatus.FAIL.getCode(), "exception while " + + "heartbeating", pkg.getHeader().getSeq())); + } finally { + Utils.writeAndFlush(res, startTime, taskExecuteTime, Objects.requireNonNull(session).getContext(), session); + } + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/HelloProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/HelloProcessor.java new file mode 100644 index 0000000000..a216561c54 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/HelloProcessor.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.tcp.client.processor; + +import static org.apache.eventmesh.common.protocol.tcp.Command.HELLO_RESPONSE; + +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.api.meta.bo.EventMeshAppSubTopicInfo; +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 java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class HelloProcessor implements TcpProcessor { + + private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); + + private EventMeshTCPServer eventMeshTCPServer; + private final Acl acl; + + public HelloProcessor(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.acl = eventMeshTCPServer.getAcl(); + } + + @Override + public void process(final Package pkg, final ChannelHandlerContext ctx, long startTime) { + long taskExecuteTime = System.currentTimeMillis(); + Package res = new Package(); + Session session = null; + UserAgent user = (UserAgent) pkg.getBody(); + try { + + // do acl check in connect + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + String group = user.getGroup(); + String token = user.getToken(); + String subsystem = user.getSubsystem(); + + if (eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerSecurityEnable()) { + EventMeshAppSubTopicInfo eventMeshAppSubTopicInfo = eventMeshTCPServer.getMetaStorage().findEventMeshAppSubTopicInfo(group); + if (eventMeshAppSubTopicInfo == null) { + throw new AclException("no group register"); + } + this.acl.doAclCheckInTcpConnect(remoteAddr, token, subsystem, eventMeshAppSubTopicInfo); + } + + if (eventMeshTCPServer.getEventMeshServer().getServiceState() != ServiceState.RUNNING) { + log.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) { + MESSAGE_LOGGER.error("HelloTask failed|address={}", ctx.channel().remoteAddress(), e); + res.setHeader(new Header(HELLO_RESPONSE, OPStatus.FAIL.getCode(), Arrays.toString(e.getStackTrace()), pkg + .getHeader().getSeq())); + ctx.writeAndFlush(res).addListener( + (ChannelFutureListener) future -> { + if (!future.isSuccess()) { + Utils.logFailedMessageFlow(future, res, user, startTime, taskExecuteTime); + } else { + Utils.logSucceedMessageFlow(res, user, startTime, taskExecuteTime); + } + log.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.equalsAny(user.getPurpose(), EventMeshConstants.PURPOSE_PUB, EventMeshConstants.PURPOSE_SUB)) { + 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/processor/ListenProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/ListenProcessor.java new file mode 100644 index 0000000000..866098a451 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/ListenProcessor.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.core.protocol.tcp.client.processor; + +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.acl.Acl; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.Session; + +import io.netty.channel.ChannelHandlerContext; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ListenProcessor implements TcpProcessor { + + private EventMeshTCPServer eventMeshTCPServer; + private final Acl acl; + + public ListenProcessor(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.acl = eventMeshTCPServer.getAcl(); + } + + @Override + public void process(final Package pkg, final ChannelHandlerContext ctx, long startTime) { + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + 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) { + log.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/processor/MessageAckProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/MessageAckProcessor.java new file mode 100644 index 0000000000..fd25d5bbd9 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/MessageAckProcessor.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.core.protocol.tcp.client.processor; + +import org.apache.eventmesh.common.protocol.tcp.Command; +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.constants.EventMeshConstants; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MessageAckProcessor implements TcpProcessor { + + private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); + private EventMeshTCPServer eventMeshTCPServer; + private final Acl acl; + + public MessageAckProcessor(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.acl = eventMeshTCPServer.getAcl(); + } + + @Override + public void process(final Package pkg, final ChannelHandlerContext ctx, long startTime) { + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + long taskExecuteTime = System.currentTimeMillis(); + String seq = pkg.getHeader().getSeq(); + Command cmd = pkg.getHeader().getCmd(); + + if (seq == null) { + log.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 != Command.RESPONSE_TO_CLIENT_ACK) { + log.warn("MessageAckTask, seq:{}, downStreamMsgContext not in downStreamMap,client:{}", + seq, session.getClient()); + } + } + MESSAGE_LOGGER.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/processor/MessageTransferProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/MessageTransferProcessor.java new file mode 100644 index 0000000000..ccbb98255b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/MessageTransferProcessor.java @@ -0,0 +1,288 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF 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.processor; + +import static org.apache.eventmesh.common.protocol.tcp.Command.RESPONSE_TO_SERVER; +import static org.apache.eventmesh.runtime.core.protocol.tcp.client.session.send.SessionSender.TRY_PERMIT_TIME_OUT; + +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.Session; +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.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.TraceUtils; +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.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.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Context; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MessageTransferProcessor implements TcpProcessor { + + private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); + private EventMeshTCPServer eventMeshTCPServer; + private final Acl acl; + + private Package pkg; + private ChannelHandlerContext ctx; + private Session session; + private long startTime; + + public MessageTransferProcessor(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.acl = eventMeshTCPServer.getAcl(); + } + + @Override + public void process(final Package pkg, final ChannelHandlerContext ctx, long startTime) { + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + + this.pkg = pkg; + this.ctx = ctx; + this.session = session; + this.startTime = startTime; + + long taskExecuteTime = System.currentTimeMillis(); + Command cmd = pkg.getHeader().getCmd(); + + try { + if (eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerTraceEnable() + && RESPONSE_TO_SERVER != 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 (Exception ex) { + log.warn("upload trace fail in MessageTransferTask[server-span-start]", ex); + } + + Command replyCmd = getReplyCmd(cmd); + Package msg = new Package(); + + 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(Objects.requireNonNull(event.getData()).toBytes(), StandardCharsets.UTF_8); + int eventMeshEventSize = eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshEventSize(); + if (content.length() > eventMeshEventSize) { + throw new Exception("event size exceeds the limit: " + eventMeshEventSize); + } + + // do acl check in sending msg + if (eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerSecurityEnable()) { + String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + this.acl.doAclCheckInTcpSend(remoteAddr, session.getClient(), event.getSubject(), cmd.getValue()); + } + + 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( + (ChannelFutureListener) future -> Utils.logSucceedMessageFlow(msg, session.getClient(), startTime, taskExecuteTime)); + + TraceUtils.finishSpanWithException(ctx, event, "Tps overload, global flow control", null); + + log.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())) { + MESSAGE_LOGGER.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) { + log.error("MessageTransferTask failed|cmd={}|event={}|user={}", cmd, event, + session.getClient(), + e); + + if (cmd != 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 == RESPONSE_TO_SERVER) { + return buildCloudEventWithTimestamps(event, + EventMeshConstants.RSP_C2EVENTMESH_TIMESTAMP, + EventMeshConstants.RSP_EVENTMESH2MQ_TIMESTAMP, sendTime, + EventMeshConstants.RSP_SEND_EVENTMESH_IP); + } else { + return buildCloudEventWithTimestamps(event, + EventMeshConstants.REQ_C2EVENTMESH_TIMESTAMP, + EventMeshConstants.REQ_EVENTMESH2MQ_TIMESTAMP, sendTime, + EventMeshConstants.REQ_SEND_EVENTMESH_IP); + } + } + + private CloudEvent buildCloudEventWithTimestamps(CloudEvent event, String client2EventMeshTime, + String eventMesh2MqTime, long sendTime, String eventMeshIP) { + return CloudEventBuilder.from(event) + .withExtension(client2EventMeshTime, String.valueOf(startTime)) + .withExtension(eventMesh2MqTime, String.valueOf(sendTime)) + .withExtension(eventMeshIP, eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshServerIp()) + .build(); + } + + 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(); + MESSAGE_LOGGER.info("upstreamMsg message success|user={}|callback cost={}", + session.getClient(), + System.currentTimeMillis() - createTime); + if (replyCmd == Command.BROADCAST_MESSAGE_TO_SERVER_ACK + || replyCmd == 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); + Objects.requireNonNull( + session.getClientGroupWrapper().get()).getTcpRetryer() + .newTimeout(upStreamMsgContext, 10, TimeUnit.SECONDS); + + session.getSender().getFailMsgCount().incrementAndGet(); + MESSAGE_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(), + 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 != 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/processor/RecommendProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/RecommendProcessor.java new file mode 100644 index 0000000000..a53a7889b5 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/RecommendProcessor.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.runtime.core.protocol.tcp.client.processor; + +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.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.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.lang3.StringUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class RecommendProcessor implements TcpProcessor { + + private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); + + private EventMeshTCPServer eventMeshTCPServer; + private final Acl acl; + + public RecommendProcessor(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.acl = eventMeshTCPServer.getAcl(); + } + + @Override + public void process(final Package pkg, final ChannelHandlerContext ctx, long startTime) { + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + long taskExecuteTime = System.currentTimeMillis(); + Package res = new Package(); + try { + if (!eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerMetaStorageEnable()) { + 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) { + MESSAGE_LOGGER.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.equalsAny(user.getPurpose(), EventMeshConstants.PURPOSE_PUB, EventMeshConstants.PURPOSE_SUB)) { + throw new Exception("client purpose config is error"); + } + } + + private String getGroupOfClient(UserAgent userAgent) { + if (userAgent == null) { + return null; + } + return userAgent.getGroup(); + } +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/SubscribeProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/SubscribeProcessor.java new file mode 100644 index 0000000000..4003fa897b --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/SubscribeProcessor.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.runtime.core.protocol.tcp.client.processor; + +import org.apache.eventmesh.api.exception.AclException; +import org.apache.eventmesh.api.meta.bo.EventMeshAppSubTopicInfo; +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.core.protocol.tcp.client.session.Session; +import org.apache.eventmesh.runtime.util.RemotingHelper; +import org.apache.eventmesh.runtime.util.Utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import io.netty.channel.ChannelHandlerContext; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SubscribeProcessor implements TcpProcessor { + + private final Acl acl; + private EventMeshTCPServer eventMeshTCPServer; + + public SubscribeProcessor(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.acl = eventMeshTCPServer.getAcl(); + } + + @Override + public void process(final Package pkg, final ChannelHandlerContext ctx, long startTime) { + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + final long taskExecuteTime = System.currentTimeMillis(); + + final Package msg = new Package(); + try { + final Subscription subscriptionInfo = (Subscription) pkg.getBody(); + Objects.requireNonNull(subscriptionInfo, "subscriptionInfo can not be null"); + + final List subscriptionItems = new ArrayList<>(); + final boolean eventMeshServerSecurityEnable = eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerSecurityEnable(); + final String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); + + String group = session.getClient().getGroup(); + String token = session.getClient().getToken(); + String subsystem = session.getClient().getSubsystem(); + + subscriptionInfo.getTopicList().forEach(item -> { + if (eventMeshServerSecurityEnable) { + try { + EventMeshAppSubTopicInfo eventMeshAppSubTopicInfo = eventMeshTCPServer.getMetaStorage().findEventMeshAppSubTopicInfo(group); + if (eventMeshAppSubTopicInfo == null) { + throw new AclException("no group register"); + } + this.acl.doAclCheckInTcpReceive(remoteAddr, token, subsystem, item.getTopic(), null, eventMeshAppSubTopicInfo); + } catch (Exception e) { + throw new AclException("group:" + session.getClient().getGroup() + " has no auth to sub the topic:" + item.getTopic()); + } + } + + subscriptionItems.add(item); + }); + + synchronized (session) { + session.subscribe(subscriptionItems); + log.info("SubscribeTask succeed|user={}|topics={}", session.getClient(), subscriptionItems); + } + eventMeshTCPServer.getClientSessionGroupMapping().updateMetaData(); + msg.setHeader(new Header(Command.SUBSCRIBE_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), pkg.getHeader().getSeq())); + } catch (Exception e) { + log.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/processor/TcpProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/TcpProcessor.java new file mode 100644 index 0000000000..01dff61c43 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/TcpProcessor.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.runtime.core.protocol.tcp.client.processor; + +import org.apache.eventmesh.common.protocol.tcp.Package; + +import io.netty.channel.ChannelHandlerContext; + +/** + * TcpProcessor + */ +public interface TcpProcessor { + + void process(final Package pkg, final ChannelHandlerContext ctx, long startTime); +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/UnSubscribeProcessor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/UnSubscribeProcessor.java new file mode 100644 index 0000000000..7706264c5c --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/processor/UnSubscribeProcessor.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.protocol.tcp.client.processor; + +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.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.Session; +import org.apache.eventmesh.runtime.util.Utils; + +import org.apache.commons.collections4.MapUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.channel.ChannelHandlerContext; + +public class UnSubscribeProcessor implements TcpProcessor { + + private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); + + private EventMeshTCPServer eventMeshTCPServer; + private final Acl acl; + + public UnSubscribeProcessor(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + this.acl = eventMeshTCPServer.getAcl(); + } + + @Override + public void process(final Package pkg, final ChannelHandlerContext ctx, long startTime) { + Session session = eventMeshTCPServer.getClientSessionGroupMapping().getSession(ctx); + long taskExecuteTime = System.currentTimeMillis(); + Package msg = new Package(); + try { + synchronized (session) { + ConcurrentHashMap subscribeTopics = session.getSessionContext().getSubscribeTopics(); + if (MapUtils.isNotEmpty(subscribeTopics)) { + List topics = new ArrayList<>(subscribeTopics.values()); + session.unsubscribe(topics); + MESSAGE_LOGGER.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) { + MESSAGE_LOGGER.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/core/protocol/tcp/client/rebalance/EventMeshRebalanceImpl.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/rebalance/EventMeshRebalanceImpl.java index 139f881971..816c17adab 100644 --- 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 @@ -17,7 +17,7 @@ package org.apache.eventmesh.runtime.core.protocol.tcp.client.rebalance; -import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; import org.apache.eventmesh.common.utils.ThreadUtils; import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; import org.apache.eventmesh.runtime.constants.EventMeshConstants; @@ -38,7 +38,6 @@ import java.util.Set; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -62,7 +61,7 @@ public void doRebalance() throws Exception { } final String cluster = eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshCluster(); - //get eventmesh of local idc + // get eventmesh of local idc Map localEventMeshMap = queryLocalEventMeshMap(cluster); if (MapUtils.isEmpty(localEventMeshMap)) { return; @@ -79,7 +78,7 @@ private Map queryLocalEventMeshMap(String cluster) { Map localEventMeshMap = null; List eventMeshDataInfoList = null; try { - eventMeshDataInfoList = eventMeshTCPServer.getRegistry().findEventMeshInfoByCluster(cluster); + eventMeshDataInfoList = eventMeshTCPServer.getMetaStorage().findEventMeshInfoByCluster(cluster); if (eventMeshDataInfoList == null || CollectionUtils.isEmpty(eventMeshDataInfoList)) { log.warn("doRebalance failed,query eventmesh instances is null from registry,cluster:{}", cluster); @@ -110,7 +109,7 @@ private Map queryLocalEventMeshMap(String cluster) { private void doRebalanceByGroup(String cluster, String group, String purpose, Map eventMeshMap) throws Exception { log.info("doRebalanceByGroup start, cluster:{}, group:{}, purpose:{}", cluster, group, purpose); - //query distribute data of local idc + // query distribute data of local idc Map clientDistributionMap = queryLocalEventMeshDistributeData(cluster, group, purpose, eventMeshMap); if (MapUtils.isEmpty(clientDistributionMap)) { @@ -129,12 +128,12 @@ private void doRebalanceRedirect(String currEventMeshName, String group, String return; } - //calculate client num need to redirect in currEventMesh + // calculate client num need to redirect in currEventMesh int judge = calculateRedirectNum(currEventMeshName, group, purpose, clientDistributionMap); if (judge > 0) { - //select redirect target eventmesh list + // select redirect target eventmesh list List eventMeshRecommendResult = selectRedirectEventMesh(group, eventMeshMap, clientDistributionMap, judge, currEventMeshName); if (eventMeshRecommendResult == null || eventMeshRecommendResult.size() != judge) { @@ -143,7 +142,7 @@ private void doRebalanceRedirect(String currEventMeshName, String group, String return; } - //do redirect + // do redirect doRedirect(group, purpose, judge, eventMeshRecommendResult); } else { log.info("rebalance condition not satisfy,group:{}, purpose:{},judge:{}", group, purpose, judge); @@ -167,7 +166,7 @@ private void doRedirect(String group, String purpose, int judge, List ev 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, + String redirectSessionAddr = EventMeshTcp2Client.redirectClient2NewEventMesh(eventMeshTCPServer.getTcpThreadPoolGroup(), newProxyIp, Integer.parseInt(newProxyPort), sessionList.get(i), eventMeshTCPServer.getClientSessionGroupMapping()); log.info("doRebalance,redirect sessionAddr:{}", redirectSessionAddr); ThreadUtils.sleep(eventMeshTCPServer.getEventMeshTCPConfiguration().getSleepIntervalInRebalanceRedirectMills(), TimeUnit.MILLISECONDS); @@ -211,8 +210,8 @@ public int calculateRedirectNum(String eventMeshName, String group, String purpo rebalanceResult = (modNum != 0 && index < modNum && index >= 0) ? avgNum + 1 : avgNum; } log.info("rebalance caculateRedirectNum,group:{}, purpose:{},sum:{},avgNum:{}," - + - "modNum:{}, index:{}, currentNum:{}, rebalanceResult:{}", group, purpose, sum, + + + "modNum:{}, index:{}, currentNum:{}, rebalanceResult:{}", group, purpose, sum, avgNum, modNum, index, currentNum, rebalanceResult); return currentNum - rebalanceResult; } @@ -222,7 +221,7 @@ private Map queryLocalEventMeshDistributeData(String cluster, S Map localEventMeshDistributeData = null; Map> eventMeshClientDistributionDataMap = null; try { - eventMeshClientDistributionDataMap = eventMeshTCPServer.getRegistry().findEventMeshClientDistributionData( + eventMeshClientDistributionDataMap = eventMeshTCPServer.getMetaStorage().findEventMeshClientDistributionData( cluster, group, purpose); if (MapUtils.isEmpty(eventMeshClientDistributionDataMap)) { 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 index 0832ae9111..913ac31036 100644 --- 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 @@ -20,23 +20,21 @@ import org.apache.eventmesh.common.EventMeshThreadFactory; import org.apache.eventmesh.common.ThreadPoolFactory; import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; -import org.apache.eventmesh.runtime.util.EventMeshUtil; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j public class EventMeshRebalanceService { - private EventMeshTCPServer eventMeshTCPServer; + private final EventMeshTCPServer eventMeshTCPServer; - private Integer rebalanceIntervalMills; + private final Integer rebalanceIntervalMills; - private EventMeshRebalanceStrategy rebalanceStrategy; + private final EventMeshRebalanceStrategy rebalanceStrategy; private ScheduledExecutorService serviceRebalanceScheduler; @@ -68,7 +66,7 @@ public void shutdown() { log.info("rebalance service shutdown......"); } - public void printRebalanceThreadPoolState() { - EventMeshUtil.printState((ThreadPoolExecutor) serviceRebalanceScheduler); + public int getRebalanceThreadPoolQueueSize() { + return ((ThreadPoolExecutor) serviceRebalanceScheduler).getQueue().size(); } } 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 index 90a0f445f7..678e1f4c30 100644 --- 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 @@ -17,7 +17,7 @@ package org.apache.eventmesh.runtime.core.protocol.tcp.client.recommend; -import org.apache.eventmesh.api.registry.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; import org.apache.eventmesh.runtime.util.ValueComparator; @@ -50,28 +50,22 @@ public String calculateRecommendEventMesh(final String group, final String purpo List eventMeshDataInfoList; if (StringUtils.isAnyBlank(group, purpose)) { - if (log.isWarnEnabled()) { - log.warn("EventMeshRecommend failed,params illegal,group:{},purpose:{}", group, purpose); - } + log.warn("EventMeshRecommend failed,params illegal,group:{},purpose:{}", group, purpose); return null; } final String cluster = eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshCluster(); try { - eventMeshDataInfoList = eventMeshTCPServer.getRegistry().findEventMeshInfoByCluster(cluster); + eventMeshDataInfoList = eventMeshTCPServer.getMetaStorage().findEventMeshInfoByCluster(cluster); } catch (Exception e) { - if (log.isWarnEnabled()) { - log.warn("EventMeshRecommend failed, findEventMeshInfoByCluster failed, cluster:{}, group:{}, purpose:{}, errMsg:{}", - cluster, group, purpose, e); - } + log.warn("EventMeshRecommend failed, findEventMeshInfoByCluster failed, cluster:{}, group:{}, purpose:{}, errMsg:{}", + cluster, group, purpose, e); return null; } if (CollectionUtils.isEmpty(eventMeshDataInfoList)) { - if (log.isWarnEnabled()) { - log.warn("EventMeshRecommend failed,not find eventMesh instances from registry,cluster:{},group:{},purpose:{}", - cluster, group, purpose); - } + log.warn("EventMeshRecommend failed, not find eventMesh instances from registry, cluster:{},group:{},purpose:{}", + cluster, group, purpose); return null; } @@ -85,17 +79,15 @@ public String calculateRecommendEventMesh(final String group, final String purpo ? localEventMeshMap.put(eventMeshDataInfo.getEventMeshName(), eventMeshDataInfo.getEndpoint()) : remoteEventMeshMap.put(eventMeshDataInfo.getEventMeshName(), eventMeshDataInfo.getEndpoint()); } else { - if (log.isErrorEnabled()) { - log.error("EventMeshName may be illegal,idc is null,eventMeshName:{}", eventMeshDataInfo.getEventMeshName()); - } + log.error("EventMeshName may be illegal,idc is null,eventMeshName:{}", eventMeshDataInfo.getEventMeshName()); } } if (MapUtils.isNotEmpty(localEventMeshMap)) { - //recommend eventmesh of local idc + // recommend eventmesh of local idc return recommendProxyByDistributeData(cluster, group, purpose, localEventMeshMap, true); } else if (MapUtils.isNotEmpty(remoteEventMeshMap)) { - //recommend eventmesh of other idc + // recommend eventmesh of other idc return recommendProxyByDistributeData(cluster, group, purpose, remoteEventMeshMap, false); } else { log.error("localEventMeshMap or remoteEventMeshMap size error"); @@ -116,20 +108,16 @@ public List calculateRedirectRecommendEventMesh(final Map(); } - if (log.isInfoEnabled()) { - log.info("eventMeshMap:{},clientDistributionMap:{},group:{},recommendNum:{},currEventMeshName:{}", - eventMeshMap, clientDistributedMap, group, recommendProxyNum, eventMeshName); - } + log.info("eventMeshMap:{},clientDistributionMap:{},group:{},recommendNum:{},currEventMeshName:{}", + eventMeshMap, clientDistributedMap, group, recommendProxyNum, eventMeshName); - //find eventmesh with least client + // find eventmesh with the least client final List> clientDistributedList = new ArrayList<>(); final ValueComparator vc = new ValueComparator(); clientDistributedMap.entrySet().forEach(clientDistributedList::add); Collections.sort(clientDistributedList, vc); - if (log.isInfoEnabled()) { - log.info("clientDistributedLists after sort:{}", clientDistributedList); - } + log.info("clientDistributedLists after sort:{}", clientDistributedList); final List recommendProxyList = new ArrayList<>(recommendProxyNum); while (recommendProxyList.size() < recommendProxyNum) { @@ -139,15 +127,11 @@ public List calculateRedirectRecommendEventMesh(final Map eventMeshMap, final boolean caculateLocal) { Objects.requireNonNull(eventMeshMap, "eventMeshMap can not be null"); - if (log.isInfoEnabled()) { - log.info("eventMeshMap:{},cluster:{},group:{},purpose:{},caculateLocal:{}", eventMeshMap, cluster, - group, purpose, caculateLocal); - } + log.info("eventMeshMap:{},cluster:{},group:{},purpose:{},caculateLocal:{}", eventMeshMap, cluster, group, purpose, caculateLocal); Map> eventMeshClientDistributionDataMap = null; try { - eventMeshClientDistributionDataMap = eventMeshTCPServer.getRegistry().findEventMeshClientDistributionData( + eventMeshClientDistributionDataMap = eventMeshTCPServer.getMetaStorage().findEventMeshClientDistributionData( cluster, group, purpose); } catch (Exception e) { - if (log.isWarnEnabled()) { - log.warn("EventMeshRecommend failed,findEventMeshClientDistributionData failed," - + "cluster:{},group:{},purpose:{}, errMsg:{}", cluster, group, purpose, e); - } + log.warn("EventMeshRecommend failed,findEventMeshClientDistributionData failed," + + "cluster:{},group:{},purpose:{}, errMsg:{}", cluster, group, purpose, e); } String recommendProxyAddr; @@ -180,10 +159,8 @@ private String recommendProxyByDistributeData(final String cluster, final String Collections.shuffle(tmpProxyAddrList); recommendProxyAddr = tmpProxyAddrList.get(0); - if (log.isInfoEnabled()) { - log.info("No distribute data in registry,cluster:{}, group:{},purpose:{}, recommendProxyAddr:{}", - cluster, group, purpose, recommendProxyAddr); - } + log.info("No distribute data in registry,cluster:{}, group:{},purpose:{}, recommendProxyAddr:{}", + cluster, group, purpose, recommendProxyAddr); return recommendProxyAddr; } @@ -199,19 +176,15 @@ private String recommendProxyByDistributeData(final String cluster, final String remoteClientDistributionMap.put(entry.getKey(), entry.getValue().get(purpose)); } } else { - if (log.isErrorEnabled()) { - log.error("eventMeshName may be illegal,idc is null,eventMeshName:{}", entry.getKey()); - } + log.error("eventMeshName may be illegal,idc is null,eventMeshName:{}", entry.getKey()); } }); recommendProxyAddr = recommendProxy(eventMeshMap, (caculateLocal == true) ? localClientDistributionMap : remoteClientDistributionMap, group); - if (log.isInfoEnabled()) { - log.info("eventMeshMap:{},group:{},purpose:{},caculateLocal:{},recommendProxyAddr:{}", eventMeshMap, - group, purpose, caculateLocal, recommendProxyAddr); - } + log.info("eventMeshMap:{},group:{},purpose:{},caculateLocal:{},recommendProxyAddr:{}", + eventMeshMap, group, purpose, caculateLocal, recommendProxyAddr); return recommendProxyAddr; } @@ -222,32 +195,24 @@ private String recommendProxy(final Map eventMeshMap, Objects.requireNonNull(eventMeshMap, "eventMeshMap can not be null"); Objects.requireNonNull(clientDistributionMap, "clientDistributionMap can not be null"); - if (log.isInfoEnabled()) { - log.info("eventMeshMap:{},clientDistributionMap:{},group:{}", eventMeshMap, clientDistributionMap, group); - } + log.info("eventMeshMap:{},clientDistributionMap:{},group:{}", eventMeshMap, clientDistributionMap, group); if (!eventMeshMap.keySet().containsAll(clientDistributionMap.keySet())) { - if (log.isWarnEnabled()) { - log.warn("exist proxy not register but exist in distributionMap"); - } + log.warn("exist proxy not register but exist in distributionMap"); return null; } eventMeshMap.keySet().forEach(proxy -> clientDistributionMap.putIfAbsent(proxy, 0)); - //select the eventmesh with least instances + // select the eventmesh with least instances if (MapUtils.isEmpty(clientDistributionMap)) { - if (log.isErrorEnabled()) { - log.error("no legal distribute data,check eventMeshMap and distributeData, group:{}", group); - } + log.error("no legal distribute data,check eventMeshMap and distributeData, group:{}", group); return null; } else { final List> list = new ArrayList<>(); clientDistributionMap.entrySet().forEach(list::add); Collections.sort(list, new ValueComparator()); - if (log.isInfoEnabled()) { - log.info("clientDistributionMap after sort:{}", list); - } + log.info("clientDistributionMap after sort:{}", list); return eventMeshMap.get(list.get(0).getKey()); } } 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 index 0d07454e46..37c5a1e372 100644 --- 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 @@ -25,6 +25,7 @@ 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.common.utils.JsonUtils; 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; @@ -39,8 +40,11 @@ import java.lang.ref.WeakReference; import java.net.InetSocketAddress; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.UUID; import java.util.concurrent.locks.ReentrantLock; import org.slf4j.Logger; @@ -51,7 +55,6 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; - import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -117,6 +120,10 @@ public class Session { @Getter protected SessionState sessionState = SessionState.CREATED; + @Setter + @Getter + private String sessionId = UUID.randomUUID().toString(); + public void notifyHeartbeat(long heartbeatTime) throws Exception { this.lastHeartbeatTime = heartbeatTime; } @@ -174,6 +181,7 @@ public void write2Client(final Package pkg) { context.writeAndFlush(pkg).addListener( new ChannelFutureListener() { + @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { @@ -186,8 +194,7 @@ public void operationComplete(ChannelFuture future) throws Exception { .incrementAndGet(); } } - } - ); + }); } catch (Exception e) { log.error("exception while write2Client", e); } @@ -195,25 +202,17 @@ public void operationComplete(ChannelFuture future) throws Exception { @Override public String toString() { - return "Session{" - + - "sysId=" + Objects.requireNonNull(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) + '}'; + Map sessionJson = new HashMap<>(); + sessionJson.put("sysId", Objects.requireNonNull(clientGroupWrapper.get()).getSysId()); + sessionJson.put("remoteAddr", RemotingHelper.parseSocketAddressAddr(remoteAddress)); + sessionJson.put("client", client); + sessionJson.put("sessionState", sessionState); + sessionJson.put("sessionContext", sessionContext); + sessionJson.put("pusher", pusher); + sessionJson.put("sender", sender); + sessionJson.put("createTime", DateFormatUtils.format(createTime, EventMeshConstants.DATE_FORMAT)); + sessionJson.put("lastHeartbeatTime", DateFormatUtils.format(lastHeartbeatTime, EventMeshConstants.DATE_FORMAT)); + return JsonUtils.toJSONString(sessionJson); } @Override @@ -231,14 +230,14 @@ public boolean equals(Object o) { if (!Objects.equals(context, session.context)) { return false; } - + return Objects.equals(sessionState, session.sessionState); } @Override public int hashCode() { - int result = 1001; //primeNumber + int result = 1001; // primeNumber if (null != client) { result += 31 * result + Objects.hash(client); } 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 index 8182bfc59e..e12405f4bc 100644 --- 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 @@ -34,7 +34,7 @@ public class SessionContext { private final ConcurrentHashMap sendTopics = new ConcurrentHashMap<>(64); @Getter - private final ConcurrentHashMap subscribeTopics = new ConcurrentHashMap<>(64); + private final ConcurrentHashMap subscribeTopics = new ConcurrentHashMap<>(64); public long createTime = System.currentTimeMillis(); 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 index 3df5c71a91..7857c342bd 100644 --- 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 @@ -31,7 +31,6 @@ import io.cloudevents.CloudEvent; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -55,8 +54,8 @@ public ClientAckContext(String seq, AbstractContext context, List ev this.events = events; this.consumer = consumer; this.createTime = System.currentTimeMillis(); - String ttlStr = events.get(0).getExtension(EventMeshConstants.PROPERTY_MESSAGE_TTL) == null ? "" : - Objects.requireNonNull(events.get(0).getExtension(EventMeshConstants.PROPERTY_MESSAGE_TTL)).toString(); + String ttlStr = events.get(0).getExtension(EventMeshConstants.PROPERTY_MESSAGE_TTL) == null ? "" + : Objects.requireNonNull(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; } @@ -125,8 +124,8 @@ public String toString() { + ",seq=" + seq + - //TODO ",consumer=" + consumer.getDefaultMQPushConsumer().getMessageModel() + - // ",consumerGroup=" + consumer.getDefaultMQPushConsumer().getConsumerGroup() + + // 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) 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 index 16a97d4cb0..1a4d53f3dc 100644 --- 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 @@ -47,12 +47,12 @@ public class DownStreamMsgContext extends RetryContext { @Setter private Session session; - private AbstractContext consumeConcurrentlyContext; + private final AbstractContext consumeConcurrentlyContext; - private MQConsumerWrapper consumer; + private final MQConsumerWrapper consumer; @Getter - private SubscriptionItem subscriptionItem; + private final SubscriptionItem subscriptionItem; private long lastPushTime; @@ -60,7 +60,7 @@ public class DownStreamMsgContext extends RetryContext { private final long expireTime; - public boolean msgFromOtherEventMesh; + private final boolean msgFromOtherEventMesh; public DownStreamMsgContext(CloudEvent event, Session session, MQConsumerWrapper consumer, AbstractContext consumeConcurrentlyContext, boolean msgFromOtherEventMesh, @@ -74,8 +74,7 @@ public DownStreamMsgContext(CloudEvent event, Session session, MQConsumerWrapper 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; + long ttl = StringUtils.isNumeric(ttlStr) ? Long.parseLong(ttlStr) : EventMeshConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS; this.expireTime = System.currentTimeMillis() + ttl; this.msgFromOtherEventMesh = msgFromOtherEventMesh; } @@ -109,7 +108,7 @@ public String toString() { + ",consumer=" + consumer + - // todo ",consumerGroup=" + consumer.getClass().getConsumerGroup() + + // todo ",consumerGroup=" + consumer.getClass().getConsumerGroup() + ",topic=" + event.getSubject() + ",subscriptionItem=" + subscriptionItem @@ -122,7 +121,6 @@ public String toString() { + '}'; } - @Override public void retry() { try { log.info("retry downStream msg start,seq:{},retryTimes:{},bizSeq:{}", this.seq, this.retryTimes, @@ -195,4 +193,8 @@ private void eventMeshAckMsg(DownStreamMsgContext downStreamMsgContext) { downStreamMsgContext.consumer.updateOffset(msgExts, downStreamMsgContext.consumeConcurrentlyContext); } + @Override + public void doRun() { + retry(); + } } 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 index 5937eebf5f..f1caa1c606 100644 --- 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 @@ -25,21 +25,20 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; - import lombok.extern.slf4j.Slf4j; @Slf4j public class PushContext { - private SessionPusher sessionPusher; + private final SessionPusher sessionPusher; - public AtomicLong deliveredMsgsCount = new AtomicLong(0); + public final AtomicLong deliveredMsgsCount = new AtomicLong(0); - public AtomicLong deliverFailMsgsCount = new AtomicLong(0); + public final AtomicLong deliverFailMsgsCount = new AtomicLong(0); - private ConcurrentHashMap unAckMsg = new ConcurrentHashMap(); + private final ConcurrentHashMap unAckMsg = new ConcurrentHashMap<>(); - private long createTime = System.currentTimeMillis(); + private final long createTime = System.currentTimeMillis(); public PushContext(SessionPusher sessionPusher) { this.sessionPusher = sessionPusher; @@ -62,7 +61,6 @@ public int getTotalUnackMsgs() { return unAckMsg.size(); } - public ConcurrentHashMap getUnAckMsg() { return unAckMsg; } 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 index 5826636697..0c000b6f43 100644 --- 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 @@ -38,6 +38,7 @@ import java.util.Arrays; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import org.slf4j.Logger; @@ -47,13 +48,12 @@ import io.netty.channel.ChannelFutureListener; import io.opentelemetry.api.trace.Span; - import lombok.extern.slf4j.Slf4j; @Slf4j public class SessionPusher { - private final Logger messageLogger = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); + private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); private final AtomicLong deliveredMsgsCount = new AtomicLong(0); @@ -105,7 +105,7 @@ public void push(final DownStreamMsgContext downStreamMsgContext) { 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()); + MESSAGE_LOGGER.info("pkg|mq2eventMesh|cmd={}|mqMsg={}|user={}", cmd, pkg, session.getClient()); } catch (Exception e) { pkg.setHeader(new Header(cmd, OPStatus.FAIL.getCode(), Arrays.toString(e.getStackTrace()), downStreamMsgContext.seq)); } finally { @@ -115,7 +115,7 @@ public void push(final DownStreamMsgContext downStreamMsgContext) { .getEventMesh2clientMsgNum() .incrementAndGet(); - //TODO uploadTrace + // TODO uploadTrace String protocolVersion = Objects.requireNonNull(downStreamMsgContext.event.getSpecVersion()).toString(); Span span = TraceUtils.prepareClientSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, downStreamMsgContext.event), @@ -129,18 +129,18 @@ public void push(final DownStreamMsgContext downStreamMsgContext) { downStreamMsgContext.retryTimes, downStreamMsgContext.event); deliverFailMsgsCount.incrementAndGet(); - //how long to isolate client when push fail + // how long to isolate client when push fail long isolateTime = System.currentTimeMillis() + session.getEventMeshTCPConfiguration().getEventMeshTcpPushFailIsolateTimeInMills(); session.setIsolateTime(isolateTime); log.warn("isolate client:{},isolateTime:{}", session.getClient(), isolateTime); - //retry + // retry long delayTime = SubscriptionType.SYNC == downStreamMsgContext.getSubscriptionItem().getType() ? session.getEventMeshTCPConfiguration().getEventMeshTcpMsgRetrySyncDelayInMills() : session.getEventMeshTCPConfiguration().getEventMeshTcpMsgRetryAsyncDelayInMills(); - downStreamMsgContext.delay(delayTime); - Objects.requireNonNull(session.getClientGroupWrapper().get()).getEventMeshTcpRetryer().pushRetry(downStreamMsgContext); + Objects.requireNonNull(session.getClientGroupWrapper().get()).getTcpRetryer() + .newTimeout(downStreamMsgContext, delayTime, TimeUnit.MILLISECONDS); } else { deliveredMsgsCount.incrementAndGet(); log.info("downstreamMsg success,seq:{}, retryTimes:{}, bizSeq:{}", downStreamMsgContext.seq, @@ -151,8 +151,7 @@ public void push(final DownStreamMsgContext downStreamMsgContext) { session.setIsolateTime(System.currentTimeMillis()); } } - } - ); + }); } finally { TraceUtils.finishSpan(span, downStreamMsgContext.event); } 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 deleted file mode 100644 index a28ae09c4b..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/retry/EventMeshTcpRetryer.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 org.apache.eventmesh.runtime.core.protocol.tcp.client.session.retry; - -import org.apache.eventmesh.common.EventMeshThreadFactory; -import org.apache.eventmesh.common.protocol.SubscriptionType; -import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; -import org.apache.eventmesh.runtime.core.protocol.RetryContext; -import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push.DownStreamMsgContext; -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 lombok.extern.slf4j.Slf4j; - -@Slf4j -public class EventMeshTcpRetryer { - - private EventMeshTCPServer eventMeshTCPServer; - - private DelayQueue retrys = new DelayQueue(); - - private ThreadPoolExecutor pool = new ThreadPoolExecutor(3, - 3, - 60000, - TimeUnit.MILLISECONDS, new ArrayBlockingQueue(1000), - new EventMeshThreadFactory("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().getEventMeshTcpMsgRetryQueueSize()) { - log.error("pushRetry fail,retrys is too much,allow max retryQueueSize:{}, retryTimes:{}, seq:{}, bizSeq:{}", - eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpMsgRetryQueueSize(), retryContext.retryTimes, - retryContext.seq, EventMeshUtil.getMessageBizSeq(retryContext.event)); - return; - } - - int maxRetryTimes = eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpMsgAsyncRetryTimes(); - if (retryContext instanceof DownStreamMsgContext) { - DownStreamMsgContext downStreamMsgContext = (DownStreamMsgContext) retryContext; - maxRetryTimes = SubscriptionType.SYNC == downStreamMsgContext.getSubscriptionItem().getType() - ? eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpMsgSyncRetryTimes() : - eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpMsgAsyncRetryTimes(); - } - - if (retryContext.retryTimes >= maxRetryTimes) { - log.warn("pushRetry fail,retry over maxRetryTimes:{}, retryTimes:{}, seq:{}, bizSeq:{}", maxRetryTimes, - retryContext.retryTimes, retryContext.seq, EventMeshUtil.getMessageBizSeq(retryContext.event)); - return; - } - - retrys.offer(retryContext); - log.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) { - final RetryContext retryCtx = retryContext; - pool.execute(() -> { - try { - retryCtx.retry(); - } catch (Exception e) { - log.error("retry-dispatcher error!", e); - } - }); - } - } catch (Exception e) { - log.error("retry-dispatcher error!", e); - } - }, "retry-dispatcher"); - dispatcher.setDaemon(true); - log.info("EventMeshTcpRetryer inited......"); - } - - public void start() throws Exception { - dispatcher.start(); - log.info("EventMeshTcpRetryer started......"); - } - - public void shutdown() { - pool.shutdown(); - log.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/TcpRetryer.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/retry/TcpRetryer.java new file mode 100644 index 0000000000..4112994400 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/session/retry/TcpRetryer.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.tcp.client.session.retry; + +import org.apache.eventmesh.common.protocol.SubscriptionType; +import org.apache.eventmesh.retry.api.AbstractRetryer; +import org.apache.eventmesh.retry.api.timer.TimerTask; +import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; +import org.apache.eventmesh.runtime.core.protocol.RetryContext; +import org.apache.eventmesh.runtime.core.protocol.tcp.client.session.push.DownStreamMsgContext; +import org.apache.eventmesh.runtime.util.EventMeshUtil; + +import java.util.concurrent.TimeUnit; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class TcpRetryer extends AbstractRetryer { + + private EventMeshTCPServer eventMeshTCPServer; + + public TcpRetryer(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + public EventMeshTCPServer getEventMeshTCPServer() { + return eventMeshTCPServer; + } + + public void setEventMeshTCPServer(EventMeshTCPServer eventMeshTCPServer) { + this.eventMeshTCPServer = eventMeshTCPServer; + } + + @Override + public void newTimeout(TimerTask timerTask, long delay, TimeUnit timeUnit) { + RetryContext retryContext = (RetryContext) timerTask; + + int maxRetryTimes = eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpMsgAsyncRetryTimes(); + if (retryContext instanceof DownStreamMsgContext) { + DownStreamMsgContext downStreamMsgContext = (DownStreamMsgContext) retryContext; + maxRetryTimes = SubscriptionType.SYNC == downStreamMsgContext.getSubscriptionItem().getType() + ? eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpMsgSyncRetryTimes() + : eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshTcpMsgAsyncRetryTimes(); + } + + if (retryContext.retryTimes >= maxRetryTimes) { + log.warn("pushRetry fail,retry over maxRetryTimes:{}, retryTimes:{}, seq:{}, bizSeq:{}", maxRetryTimes, + retryContext.retryTimes, retryContext.seq, EventMeshUtil.getMessageBizSeq(retryContext.event)); + return; + } + + super.newTimeout(timerTask, delay, timeUnit); + + log.info("pushRetry success,seq:{}, retryTimes:{}, bizSeq:{}", retryContext.seq, retryContext.retryTimes, + EventMeshUtil.getMessageBizSeq(retryContext.event)); + + } +} 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 index a967cdc89f..d9746c425a 100644 --- 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 @@ -19,11 +19,11 @@ public class EventMeshTcpSendResult { - private String seq; + private final String seq; - private EventMeshTcpSendStatus sendStatus; + private final EventMeshTcpSendStatus sendStatus; - private String detail; + private final String detail; public EventMeshTcpSendResult(String seq, EventMeshTcpSendStatus sendStatus, String detail) { this.seq = seq; 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 index da61686aae..d89d0e1710 100644 --- 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 @@ -49,7 +49,6 @@ import io.cloudevents.core.builder.CloudEventBuilder; import io.opentelemetry.api.trace.Span; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -59,13 +58,13 @@ public class SessionSender { private final transient Session session; - public transient long createTime = System.currentTimeMillis(); + public final transient long createTime = System.currentTimeMillis(); - public transient AtomicLong upMsgs = new AtomicLong(0); + public final transient AtomicLong upMsgs = new AtomicLong(0); - public transient AtomicLong failMsgCount = new AtomicLong(0); + public final transient AtomicLong failMsgCount = new AtomicLong(0); - private static final int TRY_PERMIT_TIME_OUT = 5; + public static final int TRY_PERMIT_TIME_OUT = 5; @Override public String toString() { @@ -108,7 +107,7 @@ public EventMeshTcpSendResult send(Header header, CloudEvent event, SendCallback upStreamMsgContext = new UpStreamMsgContext(session, event, header, startTime, taskExecuteTime); Span span = TraceUtils.prepareClientSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, - event), + event), EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_CLIENT_SPAN, false); try { Objects.requireNonNull(session.getClientGroupWrapper().get()) @@ -133,7 +132,7 @@ public EventMeshTcpSendResult send(Header header, CloudEvent event, SendCallback upStreamMsgContext = new UpStreamMsgContext(session, event, header, startTime, taskExecuteTime); Span span = TraceUtils.prepareClientSpan(EventMeshUtil.getCloudEventExtensionMap(protocolVersion, - event), + event), EventMeshTraceConstants.TRACE_UPSTREAM_EVENTMESH_CLIENT_SPAN, false); try { Objects.requireNonNull(session.getClientGroupWrapper().get()) @@ -169,6 +168,7 @@ public EventMeshTcpSendResult send(Header header, CloudEvent event, SendCallback private RequestReplyCallback initSyncRRCallback(Header header, long startTime, long taskExecuteTime, CloudEvent cloudEvent) { return new RequestReplyCallback() { + @Override public void onSuccess(CloudEvent event) { String seq = header.getSeq(); @@ -221,4 +221,8 @@ public void onException(Throwable e) { } }; } + + public AtomicLong getFailMsgCount() { + return failMsgCount; + } } 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 index 4ab4fd609a..d6730a9840 100644 --- 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 @@ -34,24 +34,24 @@ import org.apache.commons.lang3.time.DateFormatUtils; import java.util.Objects; +import java.util.concurrent.TimeUnit; import io.cloudevents.CloudEvent; - import lombok.extern.slf4j.Slf4j; @Slf4j public class UpStreamMsgContext extends RetryContext { - private Session session; + private final Session session; - private long createTime = System.currentTimeMillis(); + private final long createTime = System.currentTimeMillis(); - private Header header; + private final Header header; - private long startTime; + private final long startTime; - private long taskExecuteTime; + private final long taskExecuteTime; public UpStreamMsgContext(Session session, CloudEvent event, Header header, long startTime, long taskExecuteTime) { this.seq = header.getSeq(); @@ -84,7 +84,6 @@ public String toString() { + ",executeTime=" + DateFormatUtils.format(executeTime, EventMeshConstants.DATE_FORMAT); } - @Override public void retry() { log.info("retry upStream msg start,seq:{},retryTimes:{},bizSeq:{}", this.seq, this.retryTimes, EventMeshUtil.getMessageBizSeq(this.event)); @@ -117,13 +116,13 @@ protected SendCallback createSendCallback(Command replyCmd, long taskExecuteTime Package msg = new Package(); return new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { session.getSender().getUpstreamBuff().release(); log.info("upstreamMsg message success|user={}|callback cost={}", session.getClient(), System.currentTimeMillis() - createTime); - if (replyCmd == Command.BROADCAST_MESSAGE_TO_SERVER_ACK || replyCmd == Command - .ASYNC_MESSAGE_TO_SERVER_ACK) { + if (replyCmd == Command.BROADCAST_MESSAGE_TO_SERVER_ACK || replyCmd == 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); @@ -135,11 +134,10 @@ public void onException(OnExceptionContext context) { session.getSender().getUpstreamBuff().release(); // retry - // reset delay time - retryContext.delay(10000); - Objects.requireNonNull(session.getClientGroupWrapper().get()).getEventMeshTcpRetryer().pushRetry(retryContext); + Objects.requireNonNull(session.getClientGroupWrapper().get()).getTcpRetryer() + .newTimeout(retryContext, 10, TimeUnit.SECONDS); - session.getSender().failMsgCount.incrementAndGet(); + session.getSender().getFailMsgCount().incrementAndGet(); log.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)); @@ -162,4 +160,9 @@ private Command getReplyCmd(Command cmd) { return cmd; } } + + @Override + public void doRun() throws Exception { + retry(); + } } 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 deleted file mode 100644 index 4d14ecb925..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/AbstractTask.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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 io.netty.channel.ChannelHandlerContext; - -public abstract class AbstractTask implements Runnable { - - protected Package pkg; - protected ChannelHandlerContext ctx; - protected Session session; - protected long startTime; - protected EventMeshTCPServer eventMeshTCPServer; - - public AbstractTask(final Package pkg, final ChannelHandlerContext ctx, long startTime, final 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 deleted file mode 100644 index c2d1c1a8bb..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/GoodbyeTask.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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 java.util.Arrays; - -import io.netty.channel.ChannelHandlerContext; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -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) { - log.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) { - log.error("GoodbyeTask failed|user={}|errMsg={}", session.getClient(), e); - msg.setHeader(new Header(CLIENT_GOODBYE_RESPONSE, OPStatus.FAIL.getCode(), Arrays.toString(e.getStackTrace()), - pkg.getHeader().getSeq())); - } finally { - this.eventMeshTCPServer.getScheduler().submit(() -> Utils.writeAndFlush(msg, startTime, taskExecuteTime, session.getContext(), session)); - } - 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 deleted file mode 100644 index bb0465fcd8..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/HeartBeatTask.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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 java.util.Objects; - -import io.netty.channel.ChannelHandlerContext; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class HeartBeatTask extends AbstractTask { - - private final Acl acl; - - public HeartBeatTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { - super(pkg, ctx, startTime, eventMeshTCPServer); - this.acl = eventMeshTCPServer.getAcl(); - } - - @Override - public void run() { - long taskExecuteTime = System.currentTimeMillis(); - Package res = new Package(); - try { - //do acl check in heartbeat - if (eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerSecurityEnable()) { - String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - this.acl.doAclCheckInTcpHeartbeat(remoteAddr, session.getClient(), HEARTBEAT_REQUEST.getValue()); - } - - if (session != null) { - session.notifyHeartbeat(startTime); - } - res.setHeader(new Header(HEARTBEAT_RESPONSE, OPStatus.SUCCESS.getCode(), OPStatus.SUCCESS.getDesc(), - pkg.getHeader().getSeq())); - } catch (Exception e) { - log.error("HeartBeatTask failed|user={}|errMsg={}", Objects.requireNonNull(session).getClient(), e); - res.setHeader(new Header(HEARTBEAT_RESPONSE, OPStatus.FAIL.getCode(), "exception while " - + "heartbeating", pkg.getHeader().getSeq())); - } finally { - Utils.writeAndFlush(res, startTime, taskExecuteTime, Objects.requireNonNull(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 deleted file mode 100644 index e024143cc2..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/HelloTask.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; - -import static org.apache.eventmesh.common.protocol.tcp.Command.HELLO_RESPONSE; - -import org.apache.eventmesh.api.exception.AclException; -import org.apache.eventmesh.api.registry.bo.EventMeshAppSubTopicInfo; -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 java.util.Arrays; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class HelloTask extends AbstractTask { - - private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); - - private final Acl acl; - - public HelloTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { - super(pkg, ctx, startTime, eventMeshTCPServer); - this.acl = eventMeshTCPServer.getAcl(); - } - - @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 - String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - String group = user.getGroup(); - String token = user.getToken(); - String subsystem = user.getSubsystem(); - - if (eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerSecurityEnable()) { - EventMeshAppSubTopicInfo eventMeshAppSubTopicInfo = eventMeshTCPServer.getRegistry().findEventMeshAppSubTopicInfo(group); - if (eventMeshAppSubTopicInfo == null) { - throw new AclException("no group register"); - } - this.acl.doAclCheckInTcpConnect(remoteAddr, token, subsystem, eventMeshAppSubTopicInfo); - } - - if (eventMeshTCPServer.getEventMeshServer().getServiceState() != ServiceState.RUNNING) { - log.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) { - MESSAGE_LOGGER.error("HelloTask failed|address={},errMsg={}", ctx.channel().remoteAddress(), e); - res.setHeader(new Header(HELLO_RESPONSE, OPStatus.FAIL.getCode(), Arrays.toString(e.getStackTrace()), 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); - } - log.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.equalsAny(user.getPurpose(), EventMeshConstants.PURPOSE_PUB, EventMeshConstants.PURPOSE_SUB)) { - 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 deleted file mode 100644 index e9c65ce2bb..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/ListenTask.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -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) { - log.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 deleted file mode 100644 index 75e8aa7b8a..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/MessageAckTask.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.constants.EventMeshConstants; -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; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class MessageAckTask extends AbstractTask { - - private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.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) { - log.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 != Command.RESPONSE_TO_CLIENT_ACK) { - log.warn("MessageAckTask, seq:{}, downStreamMsgContext not in downStreamMap,client:{}", - seq, session.getClient()); - } - } - MESSAGE_LOGGER.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 deleted file mode 100644 index 8d00a99987..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/MessageTransferTask.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.util.RemotingHelper; -import org.apache.eventmesh.runtime.util.TraceUtils; -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.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.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.context.Context; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class MessageTransferTask extends AbstractTask { - - private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.MESSAGE); - - private static final int TRY_PERMIT_TIME_OUT = 5; - - private final Acl acl; - - public MessageTransferTask(Package pkg, ChannelHandlerContext ctx, long startTime, EventMeshTCPServer eventMeshTCPServer) { - super(pkg, ctx, startTime, eventMeshTCPServer); - this.acl = eventMeshTCPServer.getAcl(); - } - - @Override - public void run() { - long taskExecuteTime = System.currentTimeMillis(); - Command cmd = pkg.getHeader().getCmd(); - - try { - if (eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerTraceEnable() - && RESPONSE_TO_SERVER != 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) { - log.warn("upload trace fail in MessageTransferTask[server-span-start]", ex); - } - - Command replyCmd = getReplyCmd(cmd); - Package msg = new Package(); - - 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(Objects.requireNonNull(event.getData()).toBytes(), StandardCharsets.UTF_8); - int eventMeshEventSize = eventMeshTCPServer.getEventMeshTCPConfiguration().getEventMeshEventSize(); - if (content.length() > eventMeshEventSize) { - throw new Exception("event size exceeds the limit: " + eventMeshEventSize); - } - - //do acl check in sending msg - if (eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerSecurityEnable()) { - String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - this.acl.doAclCheckInTcpSend(remoteAddr, session.getClient(), event.getSubject(), cmd.getValue()); - } - - 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); - - log.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())) { - MESSAGE_LOGGER.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) { - log.error("MessageTransferTask failed|cmd={}|event={}|user={}", cmd, event, - session.getClient(), - e); - - if (cmd != 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 == 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().getEventMeshServerIp()) - .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().getEventMeshServerIp()) - .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(); - MESSAGE_LOGGER.info("upstreamMsg message success|user={}|callback cost={}", - session.getClient(), - System.currentTimeMillis() - createTime); - if (replyCmd == Command.BROADCAST_MESSAGE_TO_SERVER_ACK - || replyCmd == 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); - Objects.requireNonNull( - session.getClientGroupWrapper().get()).getEventMeshTcpRetryer() - .pushRetry(upStreamMsgContext); - - session.getSender().failMsgCount.incrementAndGet(); - MESSAGE_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(), - 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 != 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 deleted file mode 100644 index b9cb7399f7..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/RecommendTask.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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 static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.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().isEventMeshServerRegistryEnable()) { - 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) { - MESSAGE_LOGGER.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.equalsAny(user.getPurpose(), EventMeshConstants.PURPOSE_PUB, EventMeshConstants.PURPOSE_SUB)) { - throw new Exception("client purpose config is error"); - } - } - - private String getGroupOfClient(UserAgent userAgent) { - if (userAgent == null) { - return null; - } - return userAgent.getGroup(); - } -} 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 deleted file mode 100644 index 573c4d6cf0..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/SubscribeTask.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.runtime.core.protocol.tcp.client.task; - -import org.apache.eventmesh.api.exception.AclException; -import org.apache.eventmesh.api.registry.bo.EventMeshAppSubTopicInfo; -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 java.util.Objects; - -import io.netty.channel.ChannelHandlerContext; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class SubscribeTask extends AbstractTask { - - private final Acl acl; - - public SubscribeTask(final Package pkg, final ChannelHandlerContext ctx, long startTime, final EventMeshTCPServer eventMeshTCPServer) { - super(pkg, ctx, startTime, eventMeshTCPServer); - this.acl = eventMeshTCPServer.getAcl(); - } - - @Override - public void run() { - final long taskExecuteTime = System.currentTimeMillis(); - - final Package msg = new Package(); - try { - final Subscription subscriptionInfo = (Subscription) pkg.getBody(); - Objects.requireNonNull(subscriptionInfo, "subscriptionInfo can not be null"); - - final List subscriptionItems = new ArrayList<>(); - final boolean eventMeshServerSecurityEnable = eventMeshTCPServer.getEventMeshTCPConfiguration().isEventMeshServerSecurityEnable(); - final String remoteAddr = RemotingHelper.parseChannelRemoteAddr(ctx.channel()); - - String group = session.getClient().getGroup(); - String token = session.getClient().getToken(); - String subsystem = session.getClient().getSubsystem(); - - subscriptionInfo.getTopicList().forEach(item -> { - if (eventMeshServerSecurityEnable) { - try { - EventMeshAppSubTopicInfo eventMeshAppSubTopicInfo = eventMeshTCPServer.getRegistry().findEventMeshAppSubTopicInfo(group); - if (eventMeshAppSubTopicInfo == null) { - throw new AclException("no group register"); - } - this.acl.doAclCheckInTcpReceive(remoteAddr, token, subsystem, item.getTopic(), null, eventMeshAppSubTopicInfo); - } catch (Exception e) { - throw new AclException("group:" + session.getClient().getGroup() + " has no auth to sub the topic:" + item.getTopic()); - } - } - - subscriptionItems.add(item); - }); - - synchronized (session) { - session.subscribe(subscriptionItems); - if (log.isInfoEnabled()) { - log.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) { - log.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 deleted file mode 100644 index b9793e0327..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/tcp/client/task/UnSubscribeTask.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.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.constants.EventMeshConstants; -import org.apache.eventmesh.runtime.util.Utils; - -import org.apache.commons.collections4.MapUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.netty.channel.ChannelHandlerContext; - -public class UnSubscribeTask extends AbstractTask { - - private static final Logger MESSAGE_LOGGER = LoggerFactory.getLogger(EventMeshConstants.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) { - ConcurrentHashMap subscribeTopics = session.getSessionContext().getSubscribeTopics(); - if (MapUtils.isNotEmpty(subscribeTopics)) { - List topics = new ArrayList<>(subscribeTopics.values()); - session.unsubscribe(topics); - MESSAGE_LOGGER.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) { - MESSAGE_LOGGER.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/meta/MetaStorage.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/meta/MetaStorage.java new file mode 100644 index 0000000000..41da6994f7 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/meta/MetaStorage.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.meta; + +import org.apache.eventmesh.api.exception.MetaException; +import org.apache.eventmesh.api.meta.MetaService; +import org.apache.eventmesh.api.meta.MetaServiceListener; +import org.apache.eventmesh.api.meta.bo.EventMeshAppSubTopicInfo; +import org.apache.eventmesh.api.meta.bo.EventMeshServicePubTopicInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshDataInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshRegisterInfo; +import org.apache.eventmesh.api.meta.dto.EventMeshUnRegisterInfo; +import org.apache.eventmesh.spi.EventMeshExtensionFactory; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MetaStorage { + + private static final Map META_CACHE = new HashMap<>(16); + + private MetaService metaService; + + private final AtomicBoolean inited = new AtomicBoolean(false); + + private final AtomicBoolean started = new AtomicBoolean(false); + + private final AtomicBoolean shutdown = new AtomicBoolean(false); + + private MetaStorage() { + + } + + public static MetaStorage getInstance(String metaPluginType) { + return META_CACHE.computeIfAbsent(metaPluginType, MetaStorage::metaStorageBuilder); + } + + private static MetaStorage metaStorageBuilder(String metaPluginType) { + MetaService metaServiceExt = EventMeshExtensionFactory.getExtension(MetaService.class, metaPluginType); + if (metaServiceExt == null) { + String errorMsg = "can't load the metaService plugin, please check."; + log.error(errorMsg); + throw new RuntimeException(errorMsg); + } + MetaStorage metaStorage = new MetaStorage(); + metaStorage.metaService = metaServiceExt; + + return metaStorage; + } + + public void init() throws MetaException { + if (!inited.compareAndSet(false, true)) { + return; + } + metaService.init(); + } + + public void start() throws MetaException { + if (!started.compareAndSet(false, true)) { + return; + } + metaService.start(); + } + + public void shutdown() throws MetaException { + inited.compareAndSet(true, false); + started.compareAndSet(true, false); + if (!shutdown.compareAndSet(false, true)) { + return; + } + synchronized (this) { + metaService.shutdown(); + } + } + + public List findEventMeshInfoByCluster(String clusterName) throws MetaException { + return metaService.findEventMeshInfoByCluster(clusterName); + } + + public List findAllEventMeshInfo() throws MetaException { + return metaService.findAllEventMeshInfo(); + } + + public Map> findEventMeshClientDistributionData(String clusterName, String group, String purpose) + throws MetaException { + return metaService.findEventMeshClientDistributionData(clusterName, group, purpose); + } + + public void registerMetadata(Map metadata) { + metaService.registerMetadata(metadata); + } + + public void updateMetaData(Map metadata) { + metaService.updateMetaData(metadata); + } + + public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws MetaException { + return metaService.register(eventMeshRegisterInfo); + } + + public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws MetaException { + return metaService.unRegister(eventMeshUnRegisterInfo); + } + + public List findEventMeshServicePubTopicInfos() throws Exception { + return metaService.findEventMeshServicePubTopicInfos(); + } + + public EventMeshAppSubTopicInfo findEventMeshAppSubTopicInfo(String group) throws Exception { + return metaService.findEventMeshAppSubTopicInfoByGroup(group); + } + + public Map getMetaData(String key, boolean fuzzyEnabled) { + return metaService.getMetaData(key, fuzzyEnabled); + } + + public void getMetaDataWithListener(MetaServiceListener metaServiceListener, String key) throws Exception { + metaService.getMetaDataWithListener(metaServiceListener, key); + } + + public AtomicBoolean getInited() { + return inited; + } + + public AtomicBoolean getStarted() { + return started; + } +} 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 index f440e10411..0655421b79 100644 --- 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 @@ -33,7 +33,6 @@ public class MonitorMetricConstants { 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"; diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/grpc/EventMeshGrpcMonitor.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/grpc/EventMeshGrpcMonitor.java index a6d5c3f3b5..fbd3be6163 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/grpc/EventMeshGrpcMonitor.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/metrics/grpc/EventMeshGrpcMonitor.java @@ -23,7 +23,6 @@ import org.apache.eventmesh.metrics.api.model.GrpcSummaryMetrics; import org.apache.eventmesh.runtime.boot.EventMeshGrpcServer; - import java.util.List; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -64,7 +63,7 @@ public void start() throws Exception { scheduleTask = scheduler.scheduleAtFixedRate(() -> { grpcSummaryMetrics.refreshTpsMetrics(SCHEDULE_PERIOD_MILLS); grpcSummaryMetrics.clearAllMessageCounter(); - grpcSummaryMetrics.setRetrySize(eventMeshGrpcServer.getGrpcRetryer().size()); + grpcSummaryMetrics.setRetrySize(eventMeshGrpcServer.getGrpcRetryer().getPendingTimeouts()); grpcSummaryMetrics.setSubscribeTopicNum(eventMeshGrpcServer.getConsumerManager().getAllConsumerTopic().size()); }, DELAY_MILLS, SCHEDULE_PERIOD_MILLS, TimeUnit.MILLISECONDS); } 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 index 414f31778f..d0f1e01492 100644 --- 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 @@ -20,6 +20,7 @@ import org.apache.eventmesh.common.EventMeshThreadFactory; import org.apache.eventmesh.metrics.api.MetricsRegistry; import org.apache.eventmesh.metrics.api.model.HttpSummaryMetrics; +import org.apache.eventmesh.metrics.api.model.RetrySummaryMetrics; import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; import java.util.List; @@ -28,7 +29,6 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -48,27 +48,23 @@ public HTTPMetricsServer(final EventMeshHTTPServer eventMeshHTTPServer, this.eventMeshHTTPServer = eventMeshHTTPServer; this.metricsRegistries = metricsRegistries; this.summaryMetrics = new HttpSummaryMetrics( - eventMeshHTTPServer.getBatchMsgExecutor(), - eventMeshHTTPServer.getSendMsgExecutor(), - eventMeshHTTPServer.getPushMsgExecutor(), - eventMeshHTTPServer.getHttpRetryer().getFailedQueue()); + eventMeshHTTPServer.getHttpThreadPoolGroup().getBatchMsgExecutor(), + eventMeshHTTPServer.getHttpThreadPoolGroup().getSendMsgExecutor(), + eventMeshHTTPServer.getHttpThreadPoolGroup().getPushMsgExecutor(), + new RetrySummaryMetrics(eventMeshHTTPServer.getHttpRetryer().getPendingTimeouts())); init(); } private void init() { metricsRegistries.forEach(MetricsRegistry::start); - if (log.isInfoEnabled()) { - log.info("HTTPMetricsServer initialized."); - } + log.info("HTTPMetricsServer initialized."); } public void start() { metricsRegistries.forEach(metricsRegistry -> { metricsRegistry.register(summaryMetrics); - if (log.isInfoEnabled()) { - log.info("Register httpMetrics to {}", metricsRegistry.getClass().getName()); - } + log.info("Register httpMetrics to {}", metricsRegistry.getClass().getName()); }); metricsSchedule.scheduleAtFixedRate(() -> { @@ -90,17 +86,13 @@ public void start() { } }, 1000, 30 * 1000, TimeUnit.MILLISECONDS); - if (log.isInfoEnabled()) { - log.info("HTTPMetricsServer started."); - } + log.info("HTTPMetricsServer started."); } public void shutdown() { metricsSchedule.shutdown(); metricsRegistries.forEach(MetricsRegistry::showdown); - if (log.isInfoEnabled()) { - log.info("HTTPMetricsServer shutdown."); - } + log.info("HTTPMetricsServer shutdown."); } private static ScheduledExecutorService metricsSchedule = Executors.newScheduledThreadPool(2, @@ -110,76 +102,60 @@ public void shutdown() { private void logPrintServerMetrics(final HttpSummaryMetrics summaryMetrics, final EventMeshHTTPServer eventMeshHTTPServer) { - if (log.isInfoEnabled()) { - log.info("===========================================SERVER METRICS=================================================="); - - log.info("maxHTTPTPS: {}, avgHTTPTPS: {}, maxHTTPCOST: {}, avgHTTPCOST: {}, avgHTTPBodyDecodeCost: {}, httpDiscard: {}", - summaryMetrics.maxHTTPTPS(), - summaryMetrics.avgHTTPTPS(), - summaryMetrics.maxHTTPCost(), - summaryMetrics.avgHTTPCost(), - summaryMetrics.avgHTTPBodyDecodeCost(), - summaryMetrics.getHttpDiscard()); - } + log.info("===========================================SERVER METRICS=================================================="); + log.info("maxHTTPTPS: {}, avgHTTPTPS: {}, maxHTTPCOST: {}, avgHTTPCOST: {}, avgHTTPBodyDecodeCost: {}, httpDiscard: {}", + summaryMetrics.maxHTTPTPS(), + summaryMetrics.avgHTTPTPS(), + summaryMetrics.maxHTTPCost(), + summaryMetrics.avgHTTPCost(), + summaryMetrics.avgHTTPBodyDecodeCost(), + summaryMetrics.getHttpDiscard()); summaryMetrics.httpStatInfoClear(); - if (log.isInfoEnabled()) { - log.info("maxBatchSendMsgTPS: {}, avgBatchSendMsgTPS: {}, sum: {}. sumFail: {}, sumFailRate: {}, discard : {}", - summaryMetrics.maxSendBatchMsgTPS(), - summaryMetrics.avgSendBatchMsgTPS(), - summaryMetrics.getSendBatchMsgNumSum(), - summaryMetrics.getSendBatchMsgFailNumSum(), - summaryMetrics.getSendBatchMsgFailRate(), - summaryMetrics.getSendBatchMsgDiscardNumSum() - ); - } + log.info("maxBatchSendMsgTPS: {}, avgBatchSendMsgTPS: {}, sum: {}. sumFail: {}, sumFailRate: {}, discard : {}", + summaryMetrics.maxSendBatchMsgTPS(), + summaryMetrics.avgSendBatchMsgTPS(), + summaryMetrics.getSendBatchMsgNumSum(), + summaryMetrics.getSendBatchMsgFailNumSum(), + summaryMetrics.getSendBatchMsgFailRate(), + summaryMetrics.getSendBatchMsgDiscardNumSum()); summaryMetrics.cleanSendBatchStat(); - if (log.isInfoEnabled()) { - log.info("maxSendMsgTPS: {}, avgSendMsgTPS: {}, sum: {}, sumFail: {}, sumFailRate: {}, replyMsg: {}, replyFail: {}", - summaryMetrics.maxSendMsgTPS(), - summaryMetrics.avgSendMsgTPS(), - summaryMetrics.getSendMsgNumSum(), - summaryMetrics.getSendMsgFailNumSum(), - summaryMetrics.getSendMsgFailRate(), - summaryMetrics.getReplyMsgNumSum(), - summaryMetrics.getReplyMsgFailNumSum() - ); - } + log.info("maxSendMsgTPS: {}, avgSendMsgTPS: {}, sum: {}, sumFail: {}, sumFailRate: {}, replyMsg: {}, replyFail: {}", + summaryMetrics.maxSendMsgTPS(), + summaryMetrics.avgSendMsgTPS(), + summaryMetrics.getSendMsgNumSum(), + summaryMetrics.getSendMsgFailNumSum(), + summaryMetrics.getSendMsgFailRate(), + summaryMetrics.getReplyMsgNumSum(), + summaryMetrics.getReplyMsgFailNumSum()); summaryMetrics.cleanSendMsgStat(); - if (log.isInfoEnabled()) { - log.info( - "maxPushMsgTPS: {}, avgPushMsgTPS: {}, sum: {}, sumFail: {}, sumFailRate: {}, maxClientLatency: {}, avgClientLatency: {}", - summaryMetrics.maxPushMsgTPS(), - summaryMetrics.avgPushMsgTPS(), - summaryMetrics.getHttpPushMsgNumSum(), - summaryMetrics.getHttpPushFailNumSum(), - summaryMetrics.getHttpPushMsgFailRate(), - summaryMetrics.maxHTTPPushLatency(), - summaryMetrics.avgHTTPPushLatency() - ); - } + log.info("maxPushMsgTPS: {}, avgPushMsgTPS: {}, sum: {}, sumFail: {}, sumFailRate: {}, maxClientLatency: {}, avgClientLatency: {}", + summaryMetrics.maxPushMsgTPS(), + summaryMetrics.avgPushMsgTPS(), + summaryMetrics.getHttpPushMsgNumSum(), + summaryMetrics.getHttpPushFailNumSum(), + summaryMetrics.getHttpPushMsgFailRate(), + summaryMetrics.maxHTTPPushLatency(), + summaryMetrics.avgHTTPPushLatency()); summaryMetrics.cleanHttpPushMsgStat(); - if (log.isInfoEnabled()) { - log.info("batchMsgQ: {}, sendMsgQ: {}, pushMsgQ: {}, httpRetryQ: {}", - eventMeshHTTPServer.getBatchMsgExecutor().getQueue().size(), - eventMeshHTTPServer.getSendMsgExecutor().getQueue().size(), - eventMeshHTTPServer.getPushMsgExecutor().getQueue().size(), - eventMeshHTTPServer.getHttpRetryer().size()); - } - - if (log.isInfoEnabled()) { - log.info("batchAvgSend2MQCost: {}, avgSend2MQCost: {}, avgReply2MQCost: {}", - summaryMetrics.avgBatchSendMsgCost(), - summaryMetrics.avgSendMsgCost(), - summaryMetrics.avgReplyMsgCost()); - } + log.info("batchMsgQ: {}, sendMsgQ: {}, pushMsgQ: {}, httpRetryQ: {}", + eventMeshHTTPServer.getHttpThreadPoolGroup().getBatchMsgExecutor().getQueue().size(), + eventMeshHTTPServer.getHttpThreadPoolGroup().getSendMsgExecutor().getQueue().size(), + eventMeshHTTPServer.getHttpThreadPoolGroup().getPushMsgExecutor().getQueue().size(), + eventMeshHTTPServer.getHttpRetryer().getPendingTimeouts()); + + log.info("batchAvgSend2MQCost: {}, avgSend2MQCost: {}, avgReply2MQCost: {}", + summaryMetrics.avgBatchSendMsgCost(), + summaryMetrics.avgSendMsgCost(), + summaryMetrics.avgReplyMsgCost()); + summaryMetrics.send2MQStatInfoClear(); } 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 index 8800337a07..f01869ac1f 100644 --- 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 @@ -31,6 +31,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; @@ -50,9 +51,9 @@ public EventMeshTCPServer getEventMeshTCPServer() { return eventMeshTCPServer; } - private final Logger tcpLogger = LoggerFactory.getLogger("tcpMonitor"); + private static final Logger TCP_LOGGER = LoggerFactory.getLogger(EventMeshConstants.TCP_MONITOR); - private final Logger appLogger = LoggerFactory.getLogger("appMonitor"); + private static final Logger APP_LOGGER = LoggerFactory.getLogger(EventMeshConstants.APP_MONITOR); private static final int period = 60 * 1000; @@ -84,7 +85,7 @@ public void start() throws Exception { }); int delay = 60 * 1000; - monitorTpsTask = eventMeshTCPServer.getScheduler().scheduleAtFixedRate((() -> { + monitorTpsTask = eventMeshTCPServer.getTcpThreadPoolGroup().getScheduler().scheduleAtFixedRate((() -> { int msgNum = tcpSummaryMetrics.client2eventMeshMsgNum(); tcpSummaryMetrics.resetClient2EventMeshMsgNum(); tcpSummaryMetrics.setClient2eventMeshTPS((int) 1000.0d * msgNum / period); @@ -101,7 +102,7 @@ public void start() throws Exception { tcpSummaryMetrics.resetMq2eventMeshMsgNum(); tcpSummaryMetrics.setMq2eventMeshTPS((int) 1000.0d * msgNum / period); - //count topics subscribed by client in this eventMesh + // count topics subscribed by client in this eventMesh ConcurrentHashMap sessionMap = eventMeshTCPServer.getClientSessionGroupMapping().getSessionMap(); Iterator sessionIterator = sessionMap.values().iterator(); @@ -114,55 +115,61 @@ public void start() throws Exception { int sendTopics = session.getSessionContext().getSendTopics().size(); int subscribeTopics = session.getSessionContext().getSubscribeTopics().size(); - tcpLogger.info("session|deliveredFailCount={}|deliveredMsgsCount={}|unAckMsgsCount={}|sendTopics={}|subscribeTopics={}|user={}", + TCP_LOGGER.info("session|deliveredFailCount={}|deliveredMsgsCount={}|unAckMsgsCount={}|sendTopics={}|subscribeTopics={}|user={}", deliveredFailCount.longValue(), deliveredMsgsCount.longValue(), unAckMsgsCount, sendTopics, subscribeTopics, session.getClient()); topicSet.addAll(session.getSessionContext().getSubscribeTopics().keySet()); } tcpSummaryMetrics.setSubTopicNum(topicSet.size()); - tcpSummaryMetrics.setAllConnections(eventMeshTCPServer.getEventMeshTcpConnectionHandler().getConnectionCount()); + tcpSummaryMetrics.setAllConnections(eventMeshTCPServer.getTcpConnectionHandler().getConnectionCount()); printAppLogger(tcpSummaryMetrics); - }), 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( + monitorThreadPoolTask = eventMeshTCPServer.getTcpThreadPoolGroup().getScheduler().scheduleAtFixedRate(() -> { + APP_LOGGER.info("{TaskHandle:{},Send:{},Ack:{},Reply:{},Push:{},Scheduler:{},Rebalance:{}}", + eventMeshTCPServer.getTcpThreadPoolGroup().getTaskHandleExecutorService().getQueue().size(), + eventMeshTCPServer.getTcpThreadPoolGroup().getSendExecutorService().getQueue().size(), + eventMeshTCPServer.getTcpThreadPoolGroup().getAckExecutorService().getQueue().size(), + eventMeshTCPServer.getTcpThreadPoolGroup().getReplyExecutorService().getQueue().size(), + eventMeshTCPServer.getTcpThreadPoolGroup().getBroadcastMsgDownstreamExecutorService().getQueue().size(), + ((ThreadPoolExecutor) eventMeshTCPServer.getTcpThreadPoolGroup().getScheduler()).getQueue().size(), + eventMeshTCPServer.getEventMeshRebalanceService().getRebalanceThreadPoolQueueSize()); + + eventMeshTCPServer.getTcpRetryer().printState(); + + // monitor retry queue size + tcpSummaryMetrics.setRetrySize(eventMeshTCPServer.getTcpRetryer().getPendingTimeouts()); + APP_LOGGER.info( MonitorMetricConstants.EVENTMESH_MONITOR_FORMAT_COMMON, EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.RETRY_QUEUE_SIZE, tcpSummaryMetrics.getRetrySize()); - }, 10, PRINT_THREADPOOLSTATE_INTERVAL, TimeUnit.SECONDS); log.info("EventMeshTcpMonitor started......"); } private void printAppLogger(TcpSummaryMetrics tcpSummaryMetrics) { - appLogger.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.CLIENT_2_EVENTMESH_TPS, + APP_LOGGER.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.CLIENT_2_EVENTMESH_TPS, tcpSummaryMetrics.getClient2eventMeshTPS()); - appLogger.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.EVENTMESH_2_MQ_TPS, + APP_LOGGER.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.EVENTMESH_2_MQ_TPS, tcpSummaryMetrics.getEventMesh2mqTPS()); - appLogger.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.MQ_2_EVENTMESH_TPS, + APP_LOGGER.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.MQ_2_EVENTMESH_TPS, tcpSummaryMetrics.getMq2eventMeshTPS()); - appLogger.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.EVENTMESH_2_CLIENT_TPS, + APP_LOGGER.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.EVENTMESH_2_CLIENT_TPS, tcpSummaryMetrics.getEventMesh2clientTPS()); - appLogger.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.ALL_TPS, + APP_LOGGER.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.ALL_TPS, tcpSummaryMetrics.getAllTPS()); - appLogger.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.CONNECTION, + APP_LOGGER.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.CONNECTION, tcpSummaryMetrics.getAllConnections()); - appLogger.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.SUB_TOPIC_NUM, + APP_LOGGER.info("protocol: {}, s: {}, t: {}", EventMeshConstants.PROTOCOL_TCP, MonitorMetricConstants.SUB_TOPIC_NUM, tcpSummaryMetrics.getSubTopicNum()); } 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 deleted file mode 100644 index 8a7ff45008..0000000000 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/registry/Registry.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.runtime.registry; - -import org.apache.eventmesh.api.exception.RegistryException; -import org.apache.eventmesh.api.registry.RegistryService; -import org.apache.eventmesh.api.registry.bo.EventMeshAppSubTopicInfo; -import org.apache.eventmesh.api.registry.bo.EventMeshServicePubTopicInfo; -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.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class Registry { - - private static final Map REGISTRY_CACHE = new HashMap<>(16); - - private RegistryService registryService; - - private final AtomicBoolean inited = new AtomicBoolean(false); - - private final AtomicBoolean started = new AtomicBoolean(false); - - private final AtomicBoolean shutdown = new AtomicBoolean(false); - - private Registry() { - - } - - public static Registry getInstance(String registryPluginType) { - return REGISTRY_CACHE.computeIfAbsent(registryPluginType, Registry::registryBuilder); - } - - private static Registry registryBuilder(String registryPluginType) { - RegistryService registryServiceExt = EventMeshExtensionFactory.getExtension(RegistryService.class, registryPluginType); - if (registryServiceExt == null) { - String errorMsg = "can't load the registryService plugin, please check."; - log.error(errorMsg); - throw new RuntimeException(errorMsg); - } - Registry registry = new Registry(); - registry.registryService = registryServiceExt; - - return registry; - } - - public void init() throws RegistryException { - if (!inited.compareAndSet(false, true)) { - return; - } - registryService.init(); - } - - public void start() throws RegistryException { - if (!started.compareAndSet(false, true)) { - return; - } - registryService.start(); - } - - public void shutdown() throws RegistryException { - inited.compareAndSet(true, false); - started.compareAndSet(true, false); - if (!shutdown.compareAndSet(false, true)) { - return; - } - synchronized (this) { - registryService.shutdown(); - } - } - - public List findEventMeshInfoByCluster(String clusterName) throws RegistryException { - return registryService.findEventMeshInfoByCluster(clusterName); - } - - public List findAllEventMeshInfo() throws RegistryException { - return registryService.findAllEventMeshInfo(); - } - - public Map> findEventMeshClientDistributionData(String clusterName, String group, String purpose) - throws RegistryException { - return registryService.findEventMeshClientDistributionData(clusterName, group, purpose); - } - - public void registerMetadata(Map metadata) { - registryService.registerMetadata(metadata); - } - - public boolean register(EventMeshRegisterInfo eventMeshRegisterInfo) throws RegistryException { - return registryService.register(eventMeshRegisterInfo); - } - - public boolean unRegister(EventMeshUnRegisterInfo eventMeshUnRegisterInfo) throws RegistryException { - return registryService.unRegister(eventMeshUnRegisterInfo); - } - - public List findEventMeshServicePubTopicInfos() throws Exception { - return registryService.findEventMeshServicePubTopicInfos(); - } - - public EventMeshAppSubTopicInfo findEventMeshAppSubTopicInfo(String group) throws Exception { - return registryService.findEventMeshAppSubTopicInfoByGroup(group); - } -} 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 index 73e9b71dc3..826dfeb3a8 100644 --- 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 @@ -24,7 +24,6 @@ import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; - import lombok.extern.slf4j.Slf4j; /** 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 index 3a898220a0..095e30baa5 100644 --- 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 @@ -50,4 +50,3 @@ public final class SpanKey { 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 index ad1f9f74ae..3c7e48ec5b 100644 --- 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 @@ -32,7 +32,6 @@ import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.context.Context; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -129,7 +128,7 @@ public Span addTraceInfoToSpan(Span span, CloudEvent cloudEvent) { return span; } - //add trace info + // add trace info for (String entry : cloudEvent.getExtensionNames()) { span.setAttribute(entry, cloudEvent.getExtension(entry) == null ? "" : cloudEvent.getExtension(entry).toString()); } diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/BannerUtil.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/BannerUtil.java index 3e3e23aaa5..7397c5e913 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/BannerUtil.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/BannerUtil.java @@ -30,25 +30,23 @@ public class BannerUtil { private static final String LOGO = - " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME EMEMEMEME EMEMEMEME " + System.lineSeparator() - + " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME EMEMEMEMEMEMEMEME EMEMEMEMEMEMEMEMEM " + System.lineSeparator() - + " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME " + System.lineSeparator() - + "EMEMEMEMEMEM EMEMEMEMEM EMEMEMEMEMEMEMEME EMEMEMEMEME" + System.lineSeparator() - + "EMEMEMEME EMEMEMEMEM EMEMEMEMEMEME EMEMEMEME" + System.lineSeparator() - + "EMEMEME EMEMEMEME EMEME EMEMEMEM" + System.lineSeparator() - + "EMEMEME EMEMEMEME EMEMEME" + System.lineSeparator() - + "EMEMEME EMEMEMEMEM EMEMEME" + System.lineSeparator() - + "EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEM EMEMEME" + System.lineSeparator() - + "EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEM EMEMEME" + System.lineSeparator() - + "EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEM EMEMEME" + System.lineSeparator() - + "EMEMEME EMEMEMEMEM EMEMEME" + System.lineSeparator() - + "EMEMEME EMEMEMEMEM EMEMEME" + System.lineSeparator() - + "EMEMEME EMEMEMEMEM EMEMEME" + System.lineSeparator() - + "EMEMEMEME EMEMEMEMEM EMEMEMEME" + System.lineSeparator() - + "EMEMEMEMEMEM EMEMEMEMEM EMEMEMEMEMEM" + System.lineSeparator() - + " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM " + System.lineSeparator() - + " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME " + System.lineSeparator() - + " MEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME"; + " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME EMEMEMEME EMEMEMEME " + System.lineSeparator() + + " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME EMEMEMEMEMEMEMEME EMEMEMEMEMEMEMEMEM " + System.lineSeparator() + + " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME " + System.lineSeparator() + + "EMEMEMEMEMEM EMEMEMEMEM EMEMEMEMEMEMEMEME EMEMEMEMEME" + System.lineSeparator() + + "EMEMEMEME EMEMEMEMEM EMEMEMEMEMEME EMEMEMEME" + System.lineSeparator() + + "EMEMEME EMEMEMEMEM EMEME EMEMEMEM" + System.lineSeparator() + + "EMEMEME EMEMEMEMEM EMEMEME" + System.lineSeparator() + + "EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEM EMEMEME" + System.lineSeparator() + + "EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEM EMEMEME" + System.lineSeparator() + + "EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEM EMEMEME" + System.lineSeparator() + + "EMEMEME EMEMEMEMEM EMEMEME" + System.lineSeparator() + + "EMEMEME EMEMEMEMEM EMEMEME" + System.lineSeparator() + + "EMEMEMEME EMEMEMEMEM EMEMEMEME" + System.lineSeparator() + + "EMEMEMEMEMEM EMEMEMEMEM EMEMEMEMEMEM" + System.lineSeparator() + + " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM " + System.lineSeparator() + + " EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEM EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME " + System.lineSeparator() + + " MEMEMEMEMEMEMEMEMEMEMEMEMEMEME EMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEMEME"; private static final String LOGONAME = " ____ _ __ __ _ " + System.lineSeparator() @@ -60,12 +58,12 @@ public class BannerUtil { public static void generateBanner() { String banner = - System.lineSeparator() - + System.lineSeparator() - + LOGO - + System.lineSeparator() - + LOGONAME - + System.lineSeparator(); + System.lineSeparator() + + System.lineSeparator() + + LOGO + + System.lineSeparator() + + LOGONAME + + System.lineSeparator(); if (log.isInfoEnabled()) { log.info(banner); } else { 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 index 0ceb8a1238..cf03cb8f2c 100644 --- 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 @@ -25,7 +25,6 @@ import io.cloudevents.rw.CloudEventContextWriter; import io.cloudevents.rw.CloudEventRWException; - public class EventMeshCloudEventWriter implements CloudEventContextWriter { private Map extensionMap; 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 index 57a82be19c..dca254a6a5 100644 --- 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 @@ -39,6 +39,7 @@ import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.List; @@ -85,7 +86,7 @@ public static String buildMeshClientID(final String clientGroup, final String me public static String buildMeshTcpClientID(final String clientSysId, final String purpose, final String meshCluster) { return StringUtils.joinWith("-", StringUtils.trim(clientSysId), StringUtils.trim(purpose), - StringUtils.trim(meshCluster), EventMeshVersion.getCurrentVersionDesc(), ThreadUtils.getPID()); + StringUtils.trim(meshCluster), EventMeshVersion.getCurrentVersionDesc(), ThreadUtils.getPID()); } public static String buildClientGroup(final String systemId) { @@ -131,7 +132,6 @@ public static ObjectMapper createJsoner() { .setTimeZone(TimeZone.getDefault()); } - /** * print part of the mq message * @@ -163,17 +163,15 @@ public static Map getEventProp(final CloudEvent event) { final Map propMap = new HashMap<>(); event.getExtensionNames().forEach((extensionKey) -> { propMap.put(extensionKey, event.getExtension(extensionKey) == null ? "" - : event.getExtension(extensionKey).toString()); + : event.getExtension(extensionKey).toString()); }); return propMap; } public static String getLocalAddr() { - //priority of networkInterface when generating client ip + // priority of networkInterface when generating client ip final String priority = System.getProperty("networkInterface.priority", "bond1 preferList = new ArrayList<>(); preferList.addAll(Arrays.asList(priority.split("<"))); @@ -187,8 +185,7 @@ public static String getLocalAddr() { if (!preferList.contains(networkInterface.getName())) { continue; } else if (preferNetworkInterface == null - || preferList.indexOf(networkInterface.getName()) - > preferList.indexOf(preferNetworkInterface.getName())) { + || preferList.indexOf(networkInterface.getName()) > preferList.indexOf(preferNetworkInterface.getName())) { preferNetworkInterface = networkInterface; } } @@ -198,15 +195,11 @@ public static String getLocalAddr() { final ArrayList ipv6Result = new ArrayList<>(); if (preferNetworkInterface != null) { - if (log.isDebugEnabled()) { - log.debug("use preferNetworkInterface:{}", preferNetworkInterface); - } + log.debug("use preferNetworkInterface:{}", preferNetworkInterface); final Enumeration en = preferNetworkInterface.getInetAddresses(); getIpResult(ipv4Result, ipv6Result, en); } else { - if (log.isDebugEnabled()) { - log.debug("no preferNetworkInterface"); - } + log.debug("no preferNetworkInterface"); final Enumeration enumeration = NetworkInterface.getNetworkInterfaces(); while (enumeration.hasMoreElements()) { final NetworkInterface networkInterface = enumeration.nextElement(); @@ -227,7 +220,7 @@ public static String getLocalAddr() { } else if (!ipv6Result.isEmpty()) { return ipv6Result.get(0); } - //If failed to find,fall back to localhost + // If failed to find,fall back to localhost return normalizeHostAddress(InetAddress.getLocalHost()); } catch (SocketException | UnknownHostException e) { log.error("failed to get local address", e); @@ -244,7 +237,7 @@ public static String normalizeHostAddress(final InetAddress localHost) { } } - private static void getIpResult(final List ipv4Result, final List ipv6Result, + private static void getIpResult(final Collection ipv4Result, final Collection ipv6Result, final Enumeration en) { while (en.hasMoreElements()) { final InetAddress address = en.nextElement(); @@ -279,12 +272,9 @@ public static String buildUserAgentClientId(final UserAgent client) { } public static void printState(final ThreadPoolExecutor scheduledExecutorService) { - if (log.isInfoEnabled()) { - log.info("{} [{} {} {} {}]", ((EventMeshThreadFactory) scheduledExecutorService.getThreadFactory()) - .getThreadNamePrefix(), scheduledExecutorService.getQueue().size(), scheduledExecutorService - .getPoolSize(), scheduledExecutorService.getActiveCount(), scheduledExecutorService - .getCompletedTaskCount()); - } + log.info("{} [{} {} {} {}]", ((EventMeshThreadFactory) scheduledExecutorService.getThreadFactory()).getThreadNamePrefix(), + scheduledExecutorService.getQueue().size(), scheduledExecutorService.getPoolSize(), + scheduledExecutorService.getActiveCount(), scheduledExecutorService.getCompletedTaskCount()); } /** @@ -308,11 +298,9 @@ public static T cloneObject(final T object) throws IOException, ClassNotFoun } } - } - public static Map getCloudEventExtensionMap(final String protocolVersion, - final CloudEvent cloudEvent) { + public static Map getCloudEventExtensionMap(final String protocolVersion, final CloudEvent cloudEvent) { final EventMeshCloudEventWriter eventMeshCloudEventWriter = new EventMeshCloudEventWriter(); if (StringUtils.equals(SpecVersion.V1.toString(), protocolVersion) && cloudEvent instanceof CloudEventV1) { 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 index 95cf010195..ccaa13b0e2 100644 --- 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 @@ -29,6 +29,7 @@ import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; +import io.netty.util.AsciiString; public class HttpResponseUtils { @@ -44,7 +45,7 @@ public static HttpResponse createInternalServerError() { return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR); } - private static ByteBuf crateByteBuf(ChannelHandlerContext ctx, String body) { + private static ByteBuf createByteBuf(ChannelHandlerContext ctx, String body) { byte[] bytes = body.getBytes(Constants.DEFAULT_CHARSET); ByteBuf byteBuf = ctx.alloc().buffer(bytes.length); byteBuf.writeBytes(bytes); @@ -52,17 +53,18 @@ private static ByteBuf crateByteBuf(ChannelHandlerContext ctx, String body) { } public static 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); + return getHttpResponse(body, ctx, HttpHeaderValues.APPLICATION_JSON); } public static HttpResponse setResponseTextBody(String body, ChannelHandlerContext ctx) { + return getHttpResponse(body, ctx, HttpHeaderValues.TEXT_HTML); + } + + public static HttpResponse getHttpResponse(String body, ChannelHandlerContext ctx, AsciiString headerValue) { 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.add(HttpHeaderNames.CONTENT_TYPE, headerValue); + return new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, createByteBuf(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 index 744557a106..f8dc942fa6 100644 --- 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 @@ -69,7 +69,7 @@ private static String encodingParams(Collection paramValues, String enco return null; } - for (Iterator iter = paramValues.iterator(); iter.hasNext(); ) { + for (Iterator iter = paramValues.iterator(); iter.hasNext();) { sb.append(iter.next()).append("="); sb.append(URLEncoder.encode(iter.next(), encoding)); if (iter.hasNext()) { @@ -81,7 +81,7 @@ private static String encodingParams(Collection paramValues, String enco private static void setHeaders(HttpURLConnection conn, Collection headers, String encoding) { if (null != headers) { - for (Iterator iter = headers.iterator(); iter.hasNext(); ) { + for (Iterator iter = headers.iterator(); iter.hasNext();) { conn.addRequestProperty(iter.next(), iter.next()); } } 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 index 64ebacb777..2e365c0534 100644 --- 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 @@ -24,7 +24,6 @@ import io.netty.channel.Channel; - public abstract class RemotingHelper { public static String exceptionSimpleDesc(final Throwable e) { @@ -91,4 +90,3 @@ public static String parseSocketAddressAddr(final InetSocketAddress socketAddres } } - diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/ThreadPoolHelper.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/ThreadPoolHelper.java new file mode 100644 index 0000000000..1855a777c2 --- /dev/null +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/ThreadPoolHelper.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.util; + +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class ThreadPoolHelper { + + public static void printState(ThreadPoolExecutor threadPool) { + if (threadPool == null) { + log.warn("No thread pool is provided!"); + return; + } + + log.info("The ThreadPool's state=================="); + log.info("Shutdown | Terminating | Terminated: {} | {} | {}", threadPool.isShutdown(), threadPool.isTerminating(), threadPool.isTerminated()); + log.info("Active Threads: " + threadPool.getActiveCount()); + log.info("Completed Tasks / Tasks: {} / {}", threadPool.getCompletedTaskCount(), threadPool.getTaskCount()); + log.info("Queue Size: " + threadPool.getQueue().size()); + log.info("Core Pool Size: " + threadPool.getCorePoolSize()); + log.info("Maximum Pool Size: " + threadPool.getMaximumPoolSize()); + log.info("Keep Alive Time(ms): " + threadPool.getKeepAliveTime(TimeUnit.MILLISECONDS)); + log.info("The rejection policy: " + threadPool.getRejectedExecutionHandler().getClass().getSimpleName()); + log.info("========================================"); + } + +} diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/TraceUtils.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/TraceUtils.java index 0dc2b367a8..80c9cca962 100644 --- a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/TraceUtils.java +++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/util/TraceUtils.java @@ -29,7 +29,6 @@ import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.context.Context; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -80,7 +79,6 @@ public static Span prepareServerSpan(Map map, String spanName, l return span; } - public static void finishSpan(Span span, CloudEvent event) { try { log.debug("finishSpan with event:{}", event); 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 index 1bea18d08a..eb9bf9b06a 100644 --- 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 @@ -39,7 +39,6 @@ import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpRequest; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -76,8 +75,7 @@ public static void writeAndFlush(final Package pkg, long startTime, long taskExe .getEventMeshTcpMonitor().getTcpSummaryMetrics().getEventMesh2clientMsgNum().incrementAndGet(); } } - } - ); + }); } catch (Exception e) { log.error("exception while sending message to client", e); } @@ -153,8 +151,8 @@ public static Map parseHttpHeader(HttpRequest fullReq) { Map headerParam = new HashMap<>(); for (String key : fullReq.headers().names()) { if (StringUtils.equalsAnyIgnoreCase(key, HttpHeaderNames.CONTENT_TYPE.toString(), - HttpHeaderNames.ACCEPT_ENCODING.toString(), - HttpHeaderNames.CONTENT_LENGTH.toString())) { + HttpHeaderNames.ACCEPT_ENCODING.toString(), + HttpHeaderNames.CONTENT_LENGTH.toString())) { continue; } headerParam.put(key, fullReq.headers().get(key)); 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 index a84dfbd4bb..8622e6503c 100644 --- 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 @@ -23,6 +23,8 @@ public class ValueComparator implements Comparator>, Serializable { + private static final long serialVersionUID = -8734777387846774249L; + @Override public int compare(Map.Entry x, Map.Entry y) { if (x.getValue().intValue() != y.getValue().intValue()) { 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 index fa77f1b8ad..9c916bd2ae 100644 --- 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 @@ -21,6 +21,7 @@ import org.apache.eventmesh.spi.EventMeshExtensionFactory; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.validator.routines.UrlValidator; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpOptions; import org.apache.http.client.methods.HttpPost; @@ -48,30 +49,43 @@ public class WebhookUtil { private static final Map AUTH_SERVICES_MAP = new ConcurrentHashMap<>(); + private static final String[] ALLOWED_SCHEMES = new String[]{"http", "https"}; + + private static final UrlValidator URL_VALIDATOR = new UrlValidator(ALLOWED_SCHEMES); + public static boolean obtainDeliveryAgreement(final CloseableHttpClient httpClient, final String targetUrl, final String requestOrigin) { - if (log.isInfoEnabled()) { - log.info("obtain webhook delivery agreement for url: {}", targetUrl); + log.info("obtain webhook delivery agreement for url: {}", targetUrl); + + if (isInvalidUrl(targetUrl)) { + log.error("Target url is invalid url: {}", targetUrl); + return false; } final HttpOptions builder = new HttpOptions(targetUrl); builder.addHeader(REQUEST_ORIGIN_HEADER, requestOrigin); try (CloseableHttpResponse response = httpClient.execute(builder)) { - final String allowedOrigin = response.getLastHeader(ALLOWED_ORIGIN_HEADER).getValue(); + String allowedOrigin = null; + + if (response.getLastHeader(ALLOWED_ORIGIN_HEADER) != null) { + allowedOrigin = response.getLastHeader(ALLOWED_ORIGIN_HEADER).getValue(); + } return StringUtils.isEmpty(allowedOrigin) || "*".equals(allowedOrigin) || allowedOrigin.equalsIgnoreCase(requestOrigin); } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("HTTP Options Method is not supported at the Delivery Target: {}, " - + "unable to obtain the webhook delivery agreement.", targetUrl); - } + log.error("HTTP Options Method is not supported at the Delivery Target: {}, " + + "unable to obtain the webhook delivery agreement.", targetUrl); } return true; } + private static boolean isInvalidUrl(String targetUrl) { + return !URL_VALIDATOR.isValid(targetUrl); + } + public static void setWebhookHeaders(final HttpPost builder, final String contentType, final String requestOrigin, 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 index 3ae922a29f..83773f22f8 100644 --- 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 @@ -22,7 +22,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import org.apache.eventmesh.admin.rocketmq.controller.AdminController; import org.apache.eventmesh.common.config.ConfigService; import org.apache.eventmesh.metrics.api.model.HttpSummaryMetrics; import org.apache.eventmesh.metrics.api.model.TcpSummaryMetrics; @@ -30,16 +29,14 @@ import org.apache.eventmesh.runtime.boot.EventMeshHTTPServer; import org.apache.eventmesh.runtime.boot.EventMeshTCPServer; import org.apache.eventmesh.runtime.configuration.EventMeshTCPConfiguration; +import org.apache.eventmesh.runtime.meta.MetaStorage; import org.apache.eventmesh.runtime.metrics.http.HTTPMetricsServer; import org.apache.eventmesh.runtime.metrics.tcp.EventMeshTcpMonitor; -import org.apache.eventmesh.runtime.registry.Registry; import org.apache.eventmesh.webhook.admin.AdminWebHookConfigOperationManager; import org.apache.eventmesh.webhook.api.WebHookConfigOperation; -import java.io.IOException; - -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.mockito.Mockito; @@ -49,8 +46,6 @@ public class ClientManageControllerTest { @Test public void testStart() throws Exception { - AdminController adminController = mock(AdminController.class); - ConfigService configService = ConfigService.getInstance(); configService.setRootConfig("classPath://configuration.properties"); EventMeshTCPConfiguration tcpConfiguration = configService.buildConfigInstance(EventMeshTCPConfiguration.class); @@ -75,9 +70,9 @@ public void testStart() throws Exception { when(adminWebHookConfigOperationManage.getWebHookConfigOperation()).thenReturn(webHookConfigOperation); EventMeshGrpcServer eventMeshGrpcServer = mock(EventMeshGrpcServer.class); - Registry registry = mock(Registry.class); + MetaStorage metaStorage = mock(MetaStorage.class); ClientManageController controller = new ClientManageController(eventMeshTCPServer, - eventMeshHTTPServer, eventMeshGrpcServer, registry); + eventMeshHTTPServer, eventMeshGrpcServer, metaStorage); controller.setAdminWebHookConfigOperationManage(adminWebHookConfigOperationManage); eventMeshTCPServer.getEventMeshTCPConfiguration().setEventMeshStoragePluginType("standalone"); @@ -85,13 +80,7 @@ public void testStart() throws Exception { try (MockedStatic dummyStatic = Mockito.mockStatic(HttpServer.class)) { HttpServer server = mock(HttpServer.class); dummyStatic.when(() -> HttpServer.create(any(), anyInt())).thenReturn(server); - try { - Mockito.doNothing().when(adminController).run(server); - controller.start(); - } catch (IOException e) { - Assert.fail(e.getMessage()); - } - + Assertions.assertDoesNotThrow(controller::start); } } } 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 index 0b9a806480..8377c56308 100644 --- 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 @@ -37,8 +37,8 @@ import java.io.OutputStream; import java.net.URI; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.mockito.MockedConstruction; import org.mockito.MockedStatic; @@ -64,13 +64,13 @@ public void testHandle() throws Exception { String returnValue = "result"; // case 1: normal case - tcpConfiguration.setEventMeshServerRegistryEnable(true); + tcpConfiguration.setEventMeshServerMetaStorageEnable(true); when(httpExchange.getResponseBody()).thenReturn(outputStream); try (MockedConstruction ignored = mockConstruction(EventMeshRecommendImpl.class, (mock, context) -> when(mock.calculateRecommendEventMesh(anyString(), anyString())).thenReturn(returnValue))) { handler.handle(httpExchange); String response = outputStream.toString(); - Assert.assertEquals(returnValue, response); + Assertions.assertEquals(returnValue, response); } // case 2: params illegal @@ -80,11 +80,11 @@ public void testHandle() throws Exception { dummyStatic.when(() -> StringUtils.isBlank(any())).thenReturn(Boolean.TRUE); handler.handle(httpExchange); String response = outputStream.toString(); - Assert.assertEquals("params illegal!", response); + Assertions.assertEquals("params illegal!", response); } // case 3: registry disable - tcpConfiguration.setEventMeshServerRegistryEnable(false); + tcpConfiguration.setEventMeshServerMetaStorageEnable(false); outputStream = mock(ByteArrayOutputStream.class); doThrow(new IOException()).when(outputStream).close(); when(httpExchange.getResponseBody()).thenReturn(outputStream); @@ -92,7 +92,7 @@ public void testHandle() throws Exception { (mock, context) -> when(mock.calculateRecommendEventMesh(anyString(), anyString())).thenReturn(returnValue))) { handler.handle(httpExchange); String response = outputStream.toString(); - Assert.assertNotEquals(returnValue, response); + Assertions.assertNotEquals(returnValue, 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 index 68639e32c6..bafc971d8e 100644 --- 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 @@ -25,10 +25,10 @@ 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 org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import com.sun.net.httpserver.HttpExchange; @@ -36,9 +36,9 @@ public class RedirectClientByIpPortHandlerTest { private static transient RedirectClientByIpPortHandler redirectClientByIpPortHandler; - @Before + @BeforeEach public void init() { - EventMeshTCPServer mockServer = PowerMockito.mock(EventMeshTCPServer.class); + EventMeshTCPServer mockServer = Mockito.mock(EventMeshTCPServer.class); HttpHandlerManager httpHandlerManager = new HttpHandlerManager(); redirectClientByIpPortHandler = new RedirectClientByIpPortHandler(mockServer, httpHandlerManager); } @@ -48,14 +48,14 @@ 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); + HttpExchange mockExchange = Mockito.mock(HttpExchange.class); + Mockito.when(mockExchange.getResponseBody()).thenReturn(outputStream); + Mockito.when(mockExchange.getRequestURI()).thenReturn(uri); redirectClientByIpPortHandler.handle(mockExchange); String response = outputStream.toString(); - Assert.assertEquals("params illegal!", response); + Assertions.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 index 6eb07e477c..b353d527b6 100644 --- 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 @@ -45,9 +45,9 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; @@ -60,7 +60,7 @@ public class RedirectClientByPathHandlerTest { @Mock private static transient EventMeshTCPServer eventMeshTCPServer; - @Before + @BeforeEach public void init() { MockitoAnnotations.openMocks(this); } @@ -103,7 +103,7 @@ public void testHandle() throws IOException { any())).thenReturn("redirectResult"); redirectClientByPathHandler.handle(mockExchange); String response = outputStream.toString(StandardCharsets.UTF_8.name()); - Assert.assertTrue(response.startsWith("redirectClientByPath success!")); + Assertions.assertTrue(response.startsWith("redirectClientByPath success!")); } // case 2: params illegal @@ -113,7 +113,7 @@ public void testHandle() throws IOException { dummyStatic.when(() -> StringUtils.isBlank(any())).thenReturn(Boolean.TRUE); redirectClientByPathHandler.handle(mockExchange); String response = outputStream.toString(StandardCharsets.UTF_8.name()); - Assert.assertEquals("params illegal!", response); + Assertions.assertEquals("params illegal!", response); } // case 3: redirectClient2NewEventMesh fail @@ -124,7 +124,7 @@ public void testHandle() throws IOException { any())).thenThrow(new RuntimeException()); redirectClientByPathHandler.handle(mockExchange); String response = outputStream.toString(Constants.DEFAULT_CHARSET.name()); - Assert.assertTrue(response.startsWith("redirectClientByPath fail!")); + Assertions.assertTrue(response.startsWith("redirectClientByPath fail!")); } } } diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/boot/EventMeshServerTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/boot/EventMeshServerTest.java index 5f6b57b1ac..3d7cfdf877 100644 --- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/boot/EventMeshServerTest.java +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/boot/EventMeshServerTest.java @@ -26,8 +26,8 @@ import java.util.ArrayList; import java.util.List; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class EventMeshServerTest { @@ -60,56 +60,56 @@ private void testGetConfigWhenStartup(Boolean hasEnv) throws Exception { } private void assertTCPConfig(EventMeshTCPConfiguration config) { - Assert.assertEquals(config.getEventMeshTcpServerPort(), 816); - Assert.assertEquals(config.getEventMeshTcpIdleAllSeconds(), 1816); - Assert.assertEquals(config.getEventMeshTcpIdleWriteSeconds(), 2816); - Assert.assertEquals(config.getEventMeshTcpIdleReadSeconds(), 3816); - Assert.assertEquals(config.getEventMeshTcpMsgReqnumPerSecond(), Integer.valueOf(4816)); - Assert.assertEquals(config.getEventMeshTcpClientMaxNum(), 5816); - Assert.assertEquals(config.getEventMeshTcpGlobalScheduler(), 6816); - Assert.assertEquals(config.getEventMeshTcpTaskHandleExecutorPoolSize(), 7816); - Assert.assertEquals(config.getEventMeshTcpMsgDownStreamExecutorPoolSize(), 8816); - Assert.assertEquals(config.getEventMeshTcpSessionExpiredInMills(), 1816); - Assert.assertEquals(config.getEventMeshTcpSessionUpstreamBufferSize(), 11816); - Assert.assertEquals(config.getEventMeshTcpMsgAsyncRetryTimes(), 12816); - Assert.assertEquals(config.getEventMeshTcpMsgSyncRetryTimes(), 13816); - Assert.assertEquals(config.getEventMeshTcpMsgRetrySyncDelayInMills(), 14816); - Assert.assertEquals(config.getEventMeshTcpMsgRetryAsyncDelayInMills(), 15816); - Assert.assertEquals(config.getEventMeshTcpMsgRetryQueueSize(), 16816); - Assert.assertEquals(config.getEventMeshTcpRebalanceIntervalInMills(), Integer.valueOf(17816)); - Assert.assertEquals(config.getEventMeshServerAdminPort(), 18816); - Assert.assertEquals(config.isEventMeshTcpSendBackEnabled(), Boolean.TRUE); - Assert.assertEquals(config.getEventMeshTcpSendBackMaxTimes(), 3); - Assert.assertEquals(config.getEventMeshTcpPushFailIsolateTimeInMills(), 21816); - Assert.assertEquals(config.getGracefulShutdownSleepIntervalInMills(), 22816); - Assert.assertEquals(config.getSleepIntervalInRebalanceRedirectMills(), 23816); - Assert.assertEquals(config.getEventMeshEventSize(), 22816); - Assert.assertEquals(config.getEventMeshEventBatchSize(), 23816); + Assertions.assertEquals(816, config.getEventMeshTcpServerPort()); + Assertions.assertEquals(1816, config.getEventMeshTcpIdleAllSeconds()); + Assertions.assertEquals(2816, config.getEventMeshTcpIdleWriteSeconds()); + Assertions.assertEquals(3816, config.getEventMeshTcpIdleReadSeconds()); + Assertions.assertEquals(Integer.valueOf(4816), config.getEventMeshTcpMsgReqnumPerSecond()); + Assertions.assertEquals(5816, config.getEventMeshTcpClientMaxNum()); + Assertions.assertEquals(6816, config.getEventMeshTcpGlobalScheduler()); + Assertions.assertEquals(7816, config.getEventMeshTcpTaskHandleExecutorPoolSize()); + Assertions.assertEquals(8816, config.getEventMeshTcpMsgDownStreamExecutorPoolSize()); + Assertions.assertEquals(1816, config.getEventMeshTcpSessionExpiredInMills()); + Assertions.assertEquals(11816, config.getEventMeshTcpSessionUpstreamBufferSize()); + Assertions.assertEquals(12816, config.getEventMeshTcpMsgAsyncRetryTimes()); + Assertions.assertEquals(13816, config.getEventMeshTcpMsgSyncRetryTimes()); + Assertions.assertEquals(14816, config.getEventMeshTcpMsgRetrySyncDelayInMills()); + Assertions.assertEquals(15816, config.getEventMeshTcpMsgRetryAsyncDelayInMills()); + Assertions.assertEquals(16816, config.getEventMeshTcpMsgRetryQueueSize()); + Assertions.assertEquals(Integer.valueOf(17816), config.getEventMeshTcpRebalanceIntervalInMills()); + Assertions.assertEquals(18816, config.getEventMeshServerAdminPort()); + Assertions.assertEquals(Boolean.TRUE, config.isEventMeshTcpSendBackEnabled()); + Assertions.assertEquals(3, config.getEventMeshTcpSendBackMaxTimes()); + Assertions.assertEquals(21816, config.getEventMeshTcpPushFailIsolateTimeInMills()); + Assertions.assertEquals(22816, config.getGracefulShutdownSleepIntervalInMills()); + Assertions.assertEquals(23816, config.getSleepIntervalInRebalanceRedirectMills()); + Assertions.assertEquals(22816, config.getEventMeshEventSize()); + Assertions.assertEquals(23816, config.getEventMeshEventBatchSize()); } private void assertCommonConfig(CommonConfiguration config) { - Assert.assertEquals("env-succeed!!!", config.getEventMeshEnv()); - Assert.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); - Assert.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); - Assert.assertEquals("name-succeed!!!", config.getEventMeshName()); - Assert.assertEquals("816", config.getSysID()); - Assert.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); - Assert.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); - Assert.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); - Assert.assertEquals("registry-succeed!!!", config.getEventMeshRegistryPluginType()); - Assert.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); - Assert.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); + Assertions.assertEquals("env-succeed!!!", config.getEventMeshEnv()); + Assertions.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); + Assertions.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); + Assertions.assertEquals("name-succeed!!!", config.getEventMeshName()); + Assertions.assertEquals("816", config.getSysID()); + Assertions.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); + Assertions.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); + Assertions.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); + Assertions.assertEquals("metaStorage-succeed!!!", config.getEventMeshMetaStoragePluginType()); + Assertions.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); + Assertions.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); List list = new ArrayList<>(); list.add("metrics-succeed1!!!"); list.add("metrics-succeed2!!!"); list.add("metrics-succeed3!!!"); - Assert.assertEquals(list, config.getEventMeshMetricsPluginType()); + Assertions.assertEquals(list, config.getEventMeshMetricsPluginType()); - Assert.assertTrue(config.isEventMeshServerSecurityEnable()); - Assert.assertTrue(config.isEventMeshServerRegistryEnable()); - Assert.assertTrue(config.isEventMeshServerTraceEnable()); + Assertions.assertTrue(config.isEventMeshServerSecurityEnable()); + Assertions.assertTrue(config.isEventMeshServerMetaStorageEnable()); + Assertions.assertTrue(config.isEventMeshServerTraceEnable()); - Assert.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); + Assertions.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); } } 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 index 595218301f..7d88ede523 100644 --- 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 @@ -19,7 +19,6 @@ import java.util.TimeZone; - import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; 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 index 5e8340b2cd..ee57b78bcc 100644 --- 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 @@ -35,7 +35,6 @@ import io.netty.handler.codec.MessageToByteEncoder; import io.netty.handler.codec.ReplayingDecoder; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -106,8 +105,8 @@ public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) thro 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), + + + "version|flag=%s|version=%s|remoteAddress=%s", new String(flagBytes, UTF8), new String(versionBytes, UTF8), ctx.channel().remoteAddress()); throw new Exception(errorMsg); } 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 index df5c5a0d4a..90c630c709 100644 --- 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 @@ -37,7 +37,7 @@ public class MessageUtils { public static Package hello(UserAgent user) { Package msg = new Package(); - msg.setHeader(new Header(Command.HELLO_REQUEST, 0, "sucess", generateRandomString(seqLength))); + msg.setHeader(new Header(Command.HELLO_REQUEST, 0, "success", generateRandomString(seqLength))); msg.setBody(user); return msg; } @@ -230,9 +230,8 @@ public static String generateRandomString(int length) { public static Package askRecommend(UserAgent user) { Package msg = new Package(); - msg.setHeader(new Header(Command.RECOMMEND_REQUEST, 0, "sucess", generateRandomString(seqLength))); + msg.setHeader(new Header(Command.RECOMMEND_REQUEST, 0, "success", 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 index 4d2d59c15b..3991364059 100644 --- 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 @@ -21,7 +21,6 @@ import java.util.concurrent.CountDownLatch; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -77,9 +76,7 @@ public void finish(Package msg) { public static RequestContext context(Object key, Package request, CountDownLatch latch) throws Exception { RequestContext c = new RequestContext(key, request, latch); - if (log.isInfoEnabled()) { - log.info("_RequestContext|create|key=" + key); - } + log.info("_RequestContext|create|key={}", key); return c; } 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 index d81afb2a2c..5bb2c0c836 100644 --- 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 @@ -44,7 +44,6 @@ import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; - import lombok.extern.slf4j.Slf4j; /** @@ -125,6 +124,7 @@ protected synchronized void open(SimpleChannelInboundHandler handler) t .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()); @@ -144,6 +144,7 @@ protected synchronized void reconnect() throws Exception { private ChannelDuplexHandler newExceptionHandler() { return new ChannelDuplexHandler() { + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { log.warn("exceptionCaught, close connection.|remote address={}", ctx.channel().remoteAddress(), cause); 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 index c71705e90e..2602c85384 100644 --- 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 @@ -43,8 +43,8 @@ public static UserAgent createPubUserAgent() { public static UserAgent createUserAgent() { UserAgent userAgent = new UserAgent(); userAgent.setSubsystem("5123"); - //userAgent.setPid(UtilAll.getPid()); - //userAgent.setHost(RemotingUtil.getLocalAddress()); + // userAgent.setPid(UtilAll.getPid()); + // userAgent.setHost(RemotingUtil.getLocalAddress()); userAgent.setVersion("2.0.8"); userAgent.setUsername("username"); userAgent.setPassword("1234"); @@ -54,8 +54,8 @@ public static UserAgent createUserAgent() { public static UserAgent createSubUserAgent() { UserAgent userAgent = new UserAgent(); userAgent.setSubsystem("5243"); - //userAgent.setPid(UtilAll.getPid()); - //userAgent.setHost(RemotingUtil.getLocalAddress()); + // userAgent.setPid(UtilAll.getPid()); + // userAgent.setHost(RemotingUtil.getLocalAddress()); userAgent.setPort(8888); userAgent.setVersion("2.0.8"); userAgent.setUsername("username"); 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 index 03ad074c51..25798b4d6e 100644 --- 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 @@ -117,24 +117,26 @@ public String toString() { @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(); - //} + // 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 { 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 index bf07151fc2..cb6cf5dabe 100644 --- 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 @@ -31,13 +31,12 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import org.junit.Assert; +import org.junit.jupiter.api.Assertions; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -61,9 +60,7 @@ public void registerBusiHandler(ReceiveMsgHook handler) throws Exception { public void init() throws Exception { open(new Handler()); hello(); - if (log.isInfoEnabled()) { - log.info("PubClientImpl|{}|started!", clientNo); - } + log.info("PubClientImpl|{}|started!", clientNo); } public void reconnect() throws Exception { @@ -76,7 +73,7 @@ public void close() { task.cancel(false); super.close(); } catch (Exception e) { - e.printStackTrace(); + log.error("PubClientImpl|{}|close failed!", clientNo, e); } } @@ -87,10 +84,7 @@ public void heartbeat() throws Exception { PubClientImpl.this.reconnect(); } Package msg = MessageUtils.heartBeat(); - if (log.isDebugEnabled()) { - log.debug("PubClientImpl|{}|send heartbeat|Command={}|msg={}", - clientNo, msg.getHeader().getCommand(), msg); - } + log.debug("PubClientImpl|{}|send heartbeat|Command={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); PubClientImpl.this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); } catch (Exception ignored) { // ignore @@ -118,9 +112,7 @@ private void hello() throws Exception { */ @Override public Package rr(Package msg, long timeout) throws Exception { - if (log.isInfoEnabled()) { - log.info("PubClientImpl|{}|rr|send|Command={}|msg={}", clientNo, Command.REQUEST_TO_SERVER, msg); - } + log.info("PubClientImpl|{}|rr|send|Command={}|msg={}", clientNo, Command.REQUEST_TO_SERVER, msg); return dispatcher(msg, timeout); } @@ -128,31 +120,31 @@ public Package rr(Package msg, long timeout) throws Exception { * Add test case assertions on the basis of the original IO */ public Package dispatcher(Package request, long timeout) throws Exception { - Assert.assertNotNull(request); + Assertions.assertNotNull(request); Package response = super.io(request, timeout); - Assert.assertNotNull(response); + Assertions.assertNotNull(response); Command cmd = response.getHeader().getCommand(); switch (request.getHeader().getCommand()) { case RECOMMEND_REQUEST: - Assert.assertEquals(Command.RECOMMEND_RESPONSE, cmd); + Assertions.assertEquals(Command.RECOMMEND_RESPONSE, cmd); break; case HELLO_REQUEST: - Assert.assertEquals(Command.HELLO_RESPONSE, cmd); + Assertions.assertEquals(Command.HELLO_RESPONSE, cmd); break; case HEARTBEAT_REQUEST: - Assert.assertEquals(Command.HEARTBEAT_RESPONSE, cmd); + Assertions.assertEquals(Command.HEARTBEAT_RESPONSE, cmd); break; case CLIENT_GOODBYE_REQUEST: - Assert.assertEquals(Command.CLIENT_GOODBYE_RESPONSE, cmd); + Assertions.assertEquals(Command.CLIENT_GOODBYE_RESPONSE, cmd); break; case BROADCAST_MESSAGE_TO_SERVER: - Assert.assertEquals(Command.BROADCAST_MESSAGE_TO_SERVER_ACK, cmd); + Assertions.assertEquals(Command.BROADCAST_MESSAGE_TO_SERVER_ACK, cmd); break; case ASYNC_MESSAGE_TO_SERVER: - Assert.assertEquals(Command.ASYNC_MESSAGE_TO_SERVER_ACK, cmd); + Assertions.assertEquals(Command.ASYNC_MESSAGE_TO_SERVER_ACK, cmd); break; case REQUEST_TO_SERVER: - Assert.assertEquals(Command.RESPONSE_TO_CLIENT, cmd); + Assertions.assertEquals(Command.RESPONSE_TO_CLIENT, cmd); break; default: break; @@ -165,9 +157,7 @@ public Package dispatcher(Package request, long timeout) throws Exception { * Send an event message, the return value is ACCESS and ACK is given */ public Package publish(Package msg, long timeout) throws Exception { - if (log.isInfoEnabled()) { - log.info("PubClientImpl|{}|publish|send|command={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); - } + log.info("PubClientImpl|{}|publish|send|command={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); return dispatcher(msg, timeout); } @@ -175,9 +165,7 @@ public Package publish(Package msg, long timeout) throws Exception { * send broadcast message */ public Package broadcast(Package msg, long timeout) throws Exception { - if (log.isInfoEnabled()) { - log.info("PubClientImpl|{}|broadcast|send|type={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); - } + log.info("PubClientImpl|{}|broadcast|send|type={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); return dispatcher(msg, timeout); } @@ -191,9 +179,7 @@ private class Handler extends SimpleChannelInboundHandler { @Override protected void channelRead0(ChannelHandlerContext ctx, Package msg) throws Exception { - if (log.isInfoEnabled()) { - log.info("PubClientImpl|{}|receive|type={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); - } + log.info("PubClientImpl|{}|receive|type={}|msg={}", clientNo, msg.getHeader().getCommand(), msg); Command cmd = msg.getHeader().getCommand(); if (callback != null) { callback.handle(msg, ctx); 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 index f58c56fcc6..f419d0d216 100644 --- 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 @@ -38,7 +38,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import org.junit.Assert; +import org.junit.jupiter.api.Assertions; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; @@ -49,11 +49,11 @@ @Slf4j public class SubClientImpl extends TCPClient implements SubClient { - private transient UserAgent userAgent; + private final transient UserAgent userAgent; private transient ReceiveMsgHook callback; - private transient List subscriptionItems = new ArrayList(); + private final transient List subscriptionItems = new ArrayList(); private transient ScheduledFuture task; @@ -69,9 +69,7 @@ public void registerBusiHandler(ReceiveMsgHook handler) throws Exception { public void init() throws Exception { open(new Handler()); hello(); - if (log.isInfoEnabled()) { - log.info("SubClientImpl|{}|started!", clientNo); - } + log.info("SubClientImpl|{}|started!", clientNo); } public void reconnect() throws Exception { @@ -96,22 +94,16 @@ public void close() { } public void heartbeat() throws Exception { - task = scheduler.scheduleAtFixedRate(new Runnable() { - @Override - public void run() { - try { - if (!isActive()) { - SubClientImpl.this.reconnect(); - } - Package msg = MessageUtils.heartBeat(); - if (log.isDebugEnabled()) { - log.debug("SubClientImpl|{}|send heartbeat|Command={}|msg={}", clientNo, - msg.getHeader().getCommand(), msg); - } - SubClientImpl.this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); - } catch (Exception e) { - //ignore + task = scheduler.scheduleAtFixedRate(() -> { + try { + if (!isActive()) { + SubClientImpl.this.reconnect(); } + Package msg = MessageUtils.heartBeat(); + log.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); } @@ -127,7 +119,7 @@ private void hello() throws Exception { } public Package justSubscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) - throws Exception { + 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); @@ -138,19 +130,24 @@ public Package listen() throws Exception { 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); - //} + /** + * @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 { + SubscriptionType subscriptionType) throws Exception { subscriptionItems.remove(topic); Package msg = MessageUtils.unsubscribe(topic, subscriptionMode, subscriptionType); return this.dispatcher(msg, ClientConstants.DEFAULT_TIMEOUT_IN_MILLISECONDS); @@ -161,51 +158,47 @@ public UserAgent getUserAgent() { } public Package dispatcher(Package request, long timeout) throws Exception { - Assert.assertNotNull(request); + Assertions.assertNotNull(request); Package response = super.io(request, timeout); switch (request.getHeader().getCommand()) { case HELLO_REQUEST: - Assert.assertEquals(response.getHeader().getCommand(), Command.HELLO_RESPONSE); + Assertions.assertEquals(Command.HELLO_RESPONSE, response.getHeader().getCommand()); break; case HEARTBEAT_REQUEST: - Assert.assertEquals(response.getHeader().getCommand(), Command.HEARTBEAT_RESPONSE); + Assertions.assertEquals(Command.HEARTBEAT_RESPONSE, response.getHeader().getCommand()); break; case LISTEN_REQUEST: - Assert.assertEquals(response.getHeader().getCommand(), Command.LISTEN_RESPONSE); + Assertions.assertEquals(Command.LISTEN_RESPONSE, response.getHeader().getCommand()); break; case CLIENT_GOODBYE_REQUEST: - Assert.assertEquals(response.getHeader().getCommand(), Command.CLIENT_GOODBYE_RESPONSE); + Assertions.assertEquals(Command.CLIENT_GOODBYE_RESPONSE, response.getHeader().getCommand()); break; case SUBSCRIBE_REQUEST: - Assert.assertEquals(response.getHeader().getCommand(), Command.SUBSCRIBE_RESPONSE); + Assertions.assertEquals(Command.SUBSCRIBE_RESPONSE, response.getHeader().getCommand()); break; case UNSUBSCRIBE_REQUEST: - Assert.assertEquals(response.getHeader().getCommand(), Command.UNSUBSCRIBE_RESPONSE); + Assertions.assertEquals(Command.UNSUBSCRIBE_RESPONSE, response.getHeader().getCommand()); break; case SYS_LOG_TO_LOGSERVER: - Assert.assertNull(response); - break; case TRACE_LOG_TO_LOGSERVER: - Assert.assertNull(response); + Assertions.assertNull(response); break; default: break; } if (response != null) { - assert response.getHeader().getCode() == OPStatus.SUCCESS.getCode(); + Assertions.assertEquals(OPStatus.SUCCESS.getCode(), response.getHeader().getCode()); } return response; } @ChannelHandler.Sharable private class Handler extends SimpleChannelInboundHandler { + @SuppressWarnings("Duplicates") @Override protected void channelRead0(ChannelHandlerContext ctx, Package msg) throws Exception { - if (log.isInfoEnabled()) { - log.info(SubClientImpl.class.getSimpleName() + "|receive|command={}|msg={}", - msg.getHeader().getCommand(), msg); - } + log.info(SubClientImpl.class.getSimpleName() + "|receive|command={}|msg={}", msg.getHeader().getCommand(), msg); Command cmd = msg.getHeader().getCommand(); if (callback != null) { callback.handle(msg, ctx); @@ -237,7 +230,7 @@ protected void channelRead0(ChannelHandlerContext ctx, Package msg) throws Excep log.info("server goodby request: ---------------------------" + msg); close(); } else { - //control instruction set + // control instruction set RequestContext context = contexts.get(RequestContext.getHeaderSeq(msg)); if (context != null) { contexts.remove(context.getKey()); diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshGrpcConfigurationTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshGrpcConfigurationTest.java index 5481309dcc..b27b7c5f9f 100644 --- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshGrpcConfigurationTest.java +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshGrpcConfigurationTest.java @@ -23,8 +23,8 @@ import java.util.ArrayList; import java.util.List; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class EventMeshGrpcConfigurationTest { @@ -41,54 +41,54 @@ public void testGetConfigForEventMeshGrpcConfiguration() throws Exception { } private void assertGrpcConfig(EventMeshGrpcConfiguration config) { - Assert.assertEquals(816, config.getGrpcServerPort()); - Assert.assertEquals(1816, config.getEventMeshSessionExpiredInMills()); - Assert.assertEquals(Boolean.FALSE, config.isEventMeshServerBatchMsgBatchEnabled()); - Assert.assertEquals(2816, config.getEventMeshServerBatchMsgThreadNum()); - Assert.assertEquals(3816, config.getEventMeshServerSendMsgThreadNum()); - Assert.assertEquals(4816, config.getEventMeshServerPushMsgThreadNum()); - Assert.assertEquals(5816, config.getEventMeshServerReplyMsgThreadNum()); - Assert.assertEquals(6816, config.getEventMeshServerSubscribeMsgThreadNum()); - Assert.assertEquals(7816, config.getEventMeshServerRegistryThreadNum()); - Assert.assertEquals(8816, config.getEventMeshServerAdminThreadNum()); - Assert.assertEquals(9816, config.getEventMeshServerRetryThreadNum()); - Assert.assertEquals(11816, config.getEventMeshServerPullRegistryInterval()); - Assert.assertEquals(12816, config.getEventMeshServerAsyncAccumulationThreshold()); - Assert.assertEquals(13816, config.getEventMeshServerRetryBlockQueueSize()); - Assert.assertEquals(14816, config.getEventMeshServerBatchBlockQueueSize()); - Assert.assertEquals(15816, config.getEventMeshServerSendMsgBlockQueueSize()); - Assert.assertEquals(16816, config.getEventMeshServerPushMsgBlockQueueSize()); - Assert.assertEquals(17816, config.getEventMeshServerSubscribeMsgBlockQueueSize()); - Assert.assertEquals(18816, config.getEventMeshServerBusyCheckInterval()); - Assert.assertEquals(Boolean.TRUE, config.isEventMeshServerConsumerEnabled()); - Assert.assertEquals(Boolean.TRUE, config.isEventMeshServerUseTls()); - Assert.assertEquals(21816, config.getEventMeshBatchMsgRequestNumPerSecond()); - Assert.assertEquals(19816, config.getEventMeshMsgReqNumPerSecond()); + Assertions.assertEquals(816, config.getGrpcServerPort()); + Assertions.assertEquals(1816, config.getEventMeshSessionExpiredInMills()); + Assertions.assertEquals(Boolean.FALSE, config.isEventMeshServerBatchMsgBatchEnabled()); + Assertions.assertEquals(2816, config.getEventMeshServerBatchMsgThreadNum()); + Assertions.assertEquals(3816, config.getEventMeshServerSendMsgThreadNum()); + Assertions.assertEquals(4816, config.getEventMeshServerPushMsgThreadNum()); + Assertions.assertEquals(5816, config.getEventMeshServerReplyMsgThreadNum()); + Assertions.assertEquals(6816, config.getEventMeshServerSubscribeMsgThreadNum()); + Assertions.assertEquals(7816, config.getEventMeshServerMetaStorageThreadNum()); + Assertions.assertEquals(8816, config.getEventMeshServerAdminThreadNum()); + Assertions.assertEquals(9816, config.getEventMeshServerRetryThreadNum()); + Assertions.assertEquals(11816, config.getEventMeshServerPullMetaStorageInterval()); + Assertions.assertEquals(12816, config.getEventMeshServerAsyncAccumulationThreshold()); + Assertions.assertEquals(13816, config.getEventMeshServerRetryBlockQueueSize()); + Assertions.assertEquals(14816, config.getEventMeshServerBatchBlockQueueSize()); + Assertions.assertEquals(15816, config.getEventMeshServerSendMsgBlockQueueSize()); + Assertions.assertEquals(16816, config.getEventMeshServerPushMsgBlockQueueSize()); + Assertions.assertEquals(17816, config.getEventMeshServerSubscribeMsgBlockQueueSize()); + Assertions.assertEquals(18816, config.getEventMeshServerBusyCheckInterval()); + Assertions.assertEquals(Boolean.TRUE, config.isEventMeshServerConsumerEnabled()); + Assertions.assertEquals(Boolean.TRUE, config.isEventMeshServerUseTls()); + Assertions.assertEquals(21816, config.getEventMeshBatchMsgRequestNumPerSecond()); + Assertions.assertEquals(19816, config.getEventMeshMsgReqNumPerSecond()); } private void assertCommonConfig(CommonConfiguration config) { - Assert.assertEquals("env-succeed!!!", config.getEventMeshEnv()); - Assert.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); - Assert.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); - Assert.assertEquals("name-succeed!!!", config.getEventMeshName()); - Assert.assertEquals("816", config.getSysID()); - Assert.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); - Assert.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); - Assert.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); - Assert.assertEquals("registry-succeed!!!", config.getEventMeshRegistryPluginType()); - Assert.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); - Assert.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); + Assertions.assertEquals("env-succeed!!!", config.getEventMeshEnv()); + Assertions.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); + Assertions.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); + Assertions.assertEquals("name-succeed!!!", config.getEventMeshName()); + Assertions.assertEquals("816", config.getSysID()); + Assertions.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); + Assertions.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); + Assertions.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); + Assertions.assertEquals("metaStorage-succeed!!!", config.getEventMeshMetaStoragePluginType()); + Assertions.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); + Assertions.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); List list = new ArrayList<>(); list.add("metrics-succeed1!!!"); list.add("metrics-succeed2!!!"); list.add("metrics-succeed3!!!"); - Assert.assertEquals(list, config.getEventMeshMetricsPluginType()); + Assertions.assertEquals(list, config.getEventMeshMetricsPluginType()); - Assert.assertTrue(config.isEventMeshServerSecurityEnable()); - Assert.assertTrue(config.isEventMeshServerRegistryEnable()); - Assert.assertTrue(config.isEventMeshServerTraceEnable()); + Assertions.assertTrue(config.isEventMeshServerSecurityEnable()); + Assertions.assertTrue(config.isEventMeshServerMetaStorageEnable()); + Assertions.assertTrue(config.isEventMeshServerTraceEnable()); - Assert.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); + Assertions.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); } } diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshHTTPConfigurationTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshHTTPConfigurationTest.java index 27fb7bfa4e..0965744121 100644 --- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshHTTPConfigurationTest.java +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshHTTPConfigurationTest.java @@ -23,8 +23,8 @@ import java.util.ArrayList; import java.util.List; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import inet.ipaddr.AddressStringException; import inet.ipaddr.IPAddress; @@ -45,65 +45,65 @@ public void testGetEventMeshHTTPConfiguration() throws Exception { } private void assertHTTPConfig(EventMeshHTTPConfiguration config) throws AddressStringException { - Assert.assertEquals(1816, config.getHttpServerPort()); - Assert.assertEquals(Boolean.FALSE, config.isEventMeshServerBatchMsgBatchEnabled()); - Assert.assertEquals(2816, config.getEventMeshServerBatchMsgThreadNum()); - Assert.assertEquals(3816, config.getEventMeshServerSendMsgThreadNum()); - Assert.assertEquals(4816, config.getEventMeshServerPushMsgThreadNum()); - Assert.assertEquals(5816, config.getEventMeshServerReplyMsgThreadNum()); - Assert.assertEquals(6816, config.getEventMeshServerClientManageThreadNum()); - Assert.assertEquals(7816, config.getEventMeshServerRegistryThreadNum()); - Assert.assertEquals(8816, config.getEventMeshServerAdminThreadNum()); - - Assert.assertEquals(9816, config.getEventMeshServerRetryThreadNum()); - Assert.assertEquals(11816, config.getEventMeshServerPullRegistryInterval()); - Assert.assertEquals(12816, config.getEventMeshServerAsyncAccumulationThreshold()); - Assert.assertEquals(13816, config.getEventMeshServerRetryBlockQSize()); - Assert.assertEquals(14816, config.getEventMeshServerBatchBlockQSize()); - Assert.assertEquals(15816, config.getEventMeshServerSendMsgBlockQSize()); - Assert.assertEquals(16816, config.getEventMeshServerPushMsgBlockQSize()); - Assert.assertEquals(17816, config.getEventMeshServerClientManageBlockQSize()); - Assert.assertEquals(18816, config.getEventMeshServerBusyCheckInterval()); - Assert.assertEquals(Boolean.TRUE, config.isEventMeshServerConsumerEnabled()); - Assert.assertEquals(Boolean.TRUE, config.isEventMeshServerUseTls()); - Assert.assertEquals(19816, config.getEventMeshHttpMsgReqNumPerSecond()); - Assert.assertEquals(21816, config.getEventMeshBatchMsgRequestNumPerSecond()); - Assert.assertEquals(22816, config.getEventMeshEventSize()); - Assert.assertEquals(23816, config.getEventMeshEventBatchSize()); + Assertions.assertEquals(1816, config.getHttpServerPort()); + Assertions.assertEquals(Boolean.FALSE, config.isEventMeshServerBatchMsgBatchEnabled()); + Assertions.assertEquals(2816, config.getEventMeshServerBatchMsgThreadNum()); + Assertions.assertEquals(3816, config.getEventMeshServerSendMsgThreadNum()); + Assertions.assertEquals(4816, config.getEventMeshServerPushMsgThreadNum()); + Assertions.assertEquals(5816, config.getEventMeshServerReplyMsgThreadNum()); + Assertions.assertEquals(6816, config.getEventMeshServerClientManageThreadNum()); + Assertions.assertEquals(7816, config.getEventMeshServerMetaStorageThreadNum()); + Assertions.assertEquals(8816, config.getEventMeshServerAdminThreadNum()); + + Assertions.assertEquals(9816, config.getEventMeshServerRetryThreadNum()); + Assertions.assertEquals(11816, config.getEventMeshServerPullMetaStorageInterval()); + Assertions.assertEquals(12816, config.getEventMeshServerAsyncAccumulationThreshold()); + Assertions.assertEquals(13816, config.getEventMeshServerRetryBlockQSize()); + Assertions.assertEquals(14816, config.getEventMeshServerBatchBlockQSize()); + Assertions.assertEquals(15816, config.getEventMeshServerSendMsgBlockQSize()); + Assertions.assertEquals(16816, config.getEventMeshServerPushMsgBlockQSize()); + Assertions.assertEquals(17816, config.getEventMeshServerClientManageBlockQSize()); + Assertions.assertEquals(18816, config.getEventMeshServerBusyCheckInterval()); + Assertions.assertEquals(Boolean.TRUE, config.isEventMeshServerConsumerEnabled()); + Assertions.assertEquals(Boolean.TRUE, config.isEventMeshServerUseTls()); + Assertions.assertEquals(19816, config.getEventMeshHttpMsgReqNumPerSecond()); + Assertions.assertEquals(21816, config.getEventMeshBatchMsgRequestNumPerSecond()); + Assertions.assertEquals(22816, config.getEventMeshEventSize()); + Assertions.assertEquals(23816, config.getEventMeshEventBatchSize()); List list4 = new ArrayList<>(); list4.add(new IPAddressString("127.0.0.1").toAddress()); list4.add(new IPAddressString("127.0.0.2").toAddress()); - Assert.assertEquals(list4, config.getEventMeshIpv4BlackList()); + Assertions.assertEquals(list4, config.getEventMeshIpv4BlackList()); List list6 = new ArrayList<>(); list6.add(new IPAddressString("0:0:0:0:0:0:7f00:01").toAddress()); list6.add(new IPAddressString("0:0:0:0:0:0:7f00:02").toAddress()); - Assert.assertEquals(list6, config.getEventMeshIpv6BlackList()); + Assertions.assertEquals(list6, config.getEventMeshIpv6BlackList()); } private void assertCommonConfig(CommonConfiguration config) { - Assert.assertEquals("env-succeed!!!", config.getEventMeshEnv()); - Assert.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); - Assert.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); - Assert.assertEquals("name-succeed!!!", config.getEventMeshName()); - Assert.assertEquals("816", config.getSysID()); - Assert.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); - Assert.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); - Assert.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); - Assert.assertEquals("registry-succeed!!!", config.getEventMeshRegistryPluginType()); - Assert.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); - Assert.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); + Assertions.assertEquals("env-succeed!!!", config.getEventMeshEnv()); + Assertions.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); + Assertions.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); + Assertions.assertEquals("name-succeed!!!", config.getEventMeshName()); + Assertions.assertEquals("816", config.getSysID()); + Assertions.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); + Assertions.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); + Assertions.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); + Assertions.assertEquals("metaStorage-succeed!!!", config.getEventMeshMetaStoragePluginType()); + Assertions.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); + Assertions.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); List list = new ArrayList<>(); list.add("metrics-succeed1!!!"); list.add("metrics-succeed2!!!"); list.add("metrics-succeed3!!!"); - Assert.assertEquals(list, config.getEventMeshMetricsPluginType()); + Assertions.assertEquals(list, config.getEventMeshMetricsPluginType()); - Assert.assertTrue(config.isEventMeshServerSecurityEnable()); - Assert.assertTrue(config.isEventMeshServerRegistryEnable()); - Assert.assertTrue(config.isEventMeshServerTraceEnable()); + Assertions.assertTrue(config.isEventMeshServerSecurityEnable()); + Assertions.assertTrue(config.isEventMeshServerMetaStorageEnable()); + Assertions.assertTrue(config.isEventMeshServerTraceEnable()); - Assert.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); + Assertions.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); } } diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshTCPConfigurationTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshTCPConfigurationTest.java index 71a7ea19ae..c16a073d56 100644 --- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshTCPConfigurationTest.java +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/configuration/EventMeshTCPConfigurationTest.java @@ -23,8 +23,8 @@ import java.util.ArrayList; import java.util.List; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class EventMeshTCPConfigurationTest { @@ -41,56 +41,56 @@ public void testGetEventMeshTCPConfiguration() throws Exception { } private void assertTCPConfig(EventMeshTCPConfiguration config) { - Assert.assertEquals(816, config.getEventMeshTcpServerPort()); - Assert.assertEquals(1816, config.getEventMeshTcpIdleAllSeconds()); - Assert.assertEquals(2816, config.getEventMeshTcpIdleWriteSeconds()); - Assert.assertEquals(3816, config.getEventMeshTcpIdleReadSeconds()); - Assert.assertEquals(Integer.valueOf(4816), config.getEventMeshTcpMsgReqnumPerSecond()); - Assert.assertEquals(5816, config.getEventMeshTcpClientMaxNum()); - Assert.assertEquals(6816, config.getEventMeshTcpGlobalScheduler()); - Assert.assertEquals(7816, config.getEventMeshTcpTaskHandleExecutorPoolSize()); - Assert.assertEquals(8816, config.getEventMeshTcpMsgDownStreamExecutorPoolSize()); - Assert.assertEquals(1816, config.getEventMeshTcpSessionExpiredInMills()); - Assert.assertEquals(11816, config.getEventMeshTcpSessionUpstreamBufferSize()); - Assert.assertEquals(12816, config.getEventMeshTcpMsgAsyncRetryTimes()); - Assert.assertEquals(13816, config.getEventMeshTcpMsgSyncRetryTimes()); - Assert.assertEquals(14816, config.getEventMeshTcpMsgRetrySyncDelayInMills()); - Assert.assertEquals(15816, config.getEventMeshTcpMsgRetryAsyncDelayInMills()); - Assert.assertEquals(16816, config.getEventMeshTcpMsgRetryQueueSize()); - Assert.assertEquals(Integer.valueOf(17816), config.getEventMeshTcpRebalanceIntervalInMills()); - Assert.assertEquals(18816, config.getEventMeshServerAdminPort()); - Assert.assertEquals(Boolean.TRUE, config.isEventMeshTcpSendBackEnabled()); - Assert.assertEquals(3, config.getEventMeshTcpSendBackMaxTimes()); - Assert.assertEquals(21816, config.getEventMeshTcpPushFailIsolateTimeInMills()); - Assert.assertEquals(22816, config.getGracefulShutdownSleepIntervalInMills()); - Assert.assertEquals(23816, config.getSleepIntervalInRebalanceRedirectMills()); - Assert.assertEquals(22816, config.getEventMeshEventSize()); - Assert.assertEquals(23816, config.getEventMeshEventBatchSize()); + Assertions.assertEquals(816, config.getEventMeshTcpServerPort()); + Assertions.assertEquals(1816, config.getEventMeshTcpIdleAllSeconds()); + Assertions.assertEquals(2816, config.getEventMeshTcpIdleWriteSeconds()); + Assertions.assertEquals(3816, config.getEventMeshTcpIdleReadSeconds()); + Assertions.assertEquals(Integer.valueOf(4816), config.getEventMeshTcpMsgReqnumPerSecond()); + Assertions.assertEquals(5816, config.getEventMeshTcpClientMaxNum()); + Assertions.assertEquals(6816, config.getEventMeshTcpGlobalScheduler()); + Assertions.assertEquals(7816, config.getEventMeshTcpTaskHandleExecutorPoolSize()); + Assertions.assertEquals(8816, config.getEventMeshTcpMsgDownStreamExecutorPoolSize()); + Assertions.assertEquals(1816, config.getEventMeshTcpSessionExpiredInMills()); + Assertions.assertEquals(11816, config.getEventMeshTcpSessionUpstreamBufferSize()); + Assertions.assertEquals(12816, config.getEventMeshTcpMsgAsyncRetryTimes()); + Assertions.assertEquals(13816, config.getEventMeshTcpMsgSyncRetryTimes()); + Assertions.assertEquals(14816, config.getEventMeshTcpMsgRetrySyncDelayInMills()); + Assertions.assertEquals(15816, config.getEventMeshTcpMsgRetryAsyncDelayInMills()); + Assertions.assertEquals(16816, config.getEventMeshTcpMsgRetryQueueSize()); + Assertions.assertEquals(Integer.valueOf(17816), config.getEventMeshTcpRebalanceIntervalInMills()); + Assertions.assertEquals(18816, config.getEventMeshServerAdminPort()); + Assertions.assertEquals(Boolean.TRUE, config.isEventMeshTcpSendBackEnabled()); + Assertions.assertEquals(3, config.getEventMeshTcpSendBackMaxTimes()); + Assertions.assertEquals(21816, config.getEventMeshTcpPushFailIsolateTimeInMills()); + Assertions.assertEquals(22816, config.getGracefulShutdownSleepIntervalInMills()); + Assertions.assertEquals(23816, config.getSleepIntervalInRebalanceRedirectMills()); + Assertions.assertEquals(22816, config.getEventMeshEventSize()); + Assertions.assertEquals(23816, config.getEventMeshEventBatchSize()); } private void assertCommonConfig(CommonConfiguration config) { - Assert.assertEquals("env-succeed!!!", config.getEventMeshEnv()); - Assert.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); - Assert.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); - Assert.assertEquals("name-succeed!!!", config.getEventMeshName()); - Assert.assertEquals("816", config.getSysID()); - Assert.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); - Assert.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); - Assert.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); - Assert.assertEquals("registry-succeed!!!", config.getEventMeshRegistryPluginType()); - Assert.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); - Assert.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); + Assertions.assertEquals("env-succeed!!!", config.getEventMeshEnv()); + Assertions.assertEquals("idc-succeed!!!", config.getEventMeshIDC()); + Assertions.assertEquals("cluster-succeed!!!", config.getEventMeshCluster()); + Assertions.assertEquals("name-succeed!!!", config.getEventMeshName()); + Assertions.assertEquals("816", config.getSysID()); + Assertions.assertEquals("connector-succeed!!!", config.getEventMeshConnectorPluginType()); + Assertions.assertEquals("storage-succeed!!!", config.getEventMeshStoragePluginType()); + Assertions.assertEquals("security-succeed!!!", config.getEventMeshSecurityPluginType()); + Assertions.assertEquals("metaStorage-succeed!!!", config.getEventMeshMetaStoragePluginType()); + Assertions.assertEquals("trace-succeed!!!", config.getEventMeshTracePluginType()); + Assertions.assertEquals("hostIp-succeed!!!", config.getEventMeshServerIp()); List list = new ArrayList<>(); list.add("metrics-succeed1!!!"); list.add("metrics-succeed2!!!"); list.add("metrics-succeed3!!!"); - Assert.assertEquals(list, config.getEventMeshMetricsPluginType()); + Assertions.assertEquals(list, config.getEventMeshMetricsPluginType()); - Assert.assertTrue(config.isEventMeshServerSecurityEnable()); - Assert.assertTrue(config.isEventMeshServerRegistryEnable()); - Assert.assertTrue(config.isEventMeshServerTraceEnable()); + Assertions.assertTrue(config.isEventMeshServerSecurityEnable()); + Assertions.assertTrue(config.isEventMeshServerMetaStorageEnable()); + Assertions.assertTrue(config.isEventMeshServerTraceEnable()); - Assert.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); + Assertions.assertEquals("eventmesh.idc-succeed!!!", config.getEventMeshWebhookOrigin()); } } 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 index 480fe98daa..98f1114eac 100644 --- 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 @@ -17,17 +17,12 @@ 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 io.netty.channel.ChannelHandlerContext; - - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -38,13 +33,8 @@ public static void main(String[] args) throws Exception { new PubClientImpl("localhost", 10000, UserAgentUtils.createUserAgent())) { pubClient.init(); pubClient.heartbeat(); - pubClient.registerBusiHandler(new ReceiveMsgHook() { - @Override - public void handle(Package msg, ChannelHandlerContext ctx) { - if (log.isInfoEnabled()) { - log.info("server good by request: {}", msg); - } - } + pubClient.registerBusiHandler((msg, ctx) -> { + log.info("server good by request: {}", msg); }); for (int i = 0; i < 1; i++) { 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 index 3bf8099366..355d94f71d 100644 --- 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 @@ -20,15 +20,10 @@ 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 io.netty.channel.ChannelHandlerContext; - - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -36,19 +31,14 @@ public class AsyncSubClient { public static void main(String[] args) throws Exception { try (SubClientImpl client = - new SubClientImpl("localhost", 10002, MessageUtils.generateSubServer())) { + new SubClientImpl("localhost", 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(); - if (log.isInfoEnabled()) { - log.info("receive message -------------------------------" + body); - } - } + client.registerBusiHandler((msg, ctx) -> { + if (msg.getBody() instanceof EventMeshMessage) { + String body = ((EventMeshMessage) msg.getBody()).getBody(); + log.info("receive message : {}", body); } }); } 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 index c174cb3e27..72ac6d98e2 100644 --- 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 @@ -21,15 +21,10 @@ 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 io.netty.channel.ChannelHandlerContext; - - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -40,16 +35,11 @@ public static void main(String[] args) throws Exception { 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(); - if (log.isInfoEnabled()) { - log.info("receive message -------------------------------" + body); - } - } + client.registerBusiHandler((msg, ctx) -> { + if (msg.getHeader().getCommand() == Command.BROADCAST_MESSAGE_TO_CLIENT) { + if (msg.getBody() instanceof EventMeshMessage) { + String body = ((EventMeshMessage) msg.getBody()).getBody(); + log.info("receive message : {}", body); } } }); 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 index a2c6873cce..a604bd8b5e 100644 --- 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 @@ -23,12 +23,8 @@ 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 io.netty.channel.ChannelHandlerContext; - - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -41,16 +37,11 @@ public static void main(String[] args) throws Exception { 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) { - if (log.isInfoEnabled()) { - log.info("Received message: {}", msg); - } - if (msg.getHeader().getCommand() == Command.REQUEST_TO_CLIENT) { - Package rrResponse = MessageUtils.rrResponse(msg); - ctx.writeAndFlush(rrResponse); - } + subClient.registerBusiHandler((msg, ctx) -> { + log.info("Received message: {}", msg); + 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 index 580fe5cd82..59599a11ad 100644 --- 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 @@ -20,13 +20,9 @@ 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 io.netty.channel.ChannelHandlerContext; - import lombok.extern.slf4j.Slf4j; /** @@ -45,20 +41,15 @@ public static void main(String[] args) throws Exception { 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) { - if (log.isInfoEnabled()) { - log.info("receive message: {}", msg); - } - } + client.registerSubBusiHandler((msg, ctx) -> { + if (msg.getHeader().getCmd() == Command.ASYNC_MESSAGE_TO_CLIENT || msg.getHeader().getCmd() == Command.BROADCAST_MESSAGE_TO_CLIENT) { + log.info("receive message: {}", msg); } }); for (int i = 0; i < 10000; i++) { - //broadcast message + // broadcast message client.broadcast(MessageUtils.broadcastMessage("TEST-TOPIC-TCP-BROADCAST", i), 5000); - //asynchronous message + // asynchronous message client.publish(MessageUtils.asyncMessage(ASYNC_TOPIC, i), 5000); } } 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 index 855738acbe..8b23d2a829 100644 --- 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 @@ -30,7 +30,7 @@ public class SyncPubClient { public static void main(String[] args) throws Exception { try (PubClientImpl pubClient = - new PubClientImpl("localhost", 10000, UserAgentUtils.createUserAgent())) { + new PubClientImpl("localhost", 10000, UserAgentUtils.createUserAgent())) { pubClient.init(); pubClient.heartbeat(); @@ -38,10 +38,7 @@ public static void main(String[] args) throws Exception { Package rr = pubClient.rr(MessageUtils.rrMesssage("TEST-TOPIC-TCP-SYNC", i), 3000); if (rr.getBody() instanceof EventMeshMessage) { String body = ((EventMeshMessage) rr.getBody()).getBody(); - if (log.isInfoEnabled()) { - log.info("rrMessage: " + body + " " - + "rr-reply-------------------------------------------------" + rr); - } + log.info("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 index 010555a10c..c64f6ac570 100644 --- 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 @@ -20,15 +20,10 @@ 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 io.netty.channel.ChannelHandlerContext; - - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -36,18 +31,13 @@ public class SyncSubClient { public static void main(String[] args) throws Exception { try (SubClientImpl client = - new SubClientImpl("localhost", 10000, MessageUtils.generateSubServer())) { + new SubClientImpl("localhost", 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) { - if ((log.isInfoEnabled())) { - log.info("receive message -------------------------------" + msg); - } - } + client.registerBusiHandler((msg, ctx) -> { + if (msg.getHeader().getCommand() == Command.REQUEST_TO_CLIENT) { + log.info("receive message:{}", msg); } }); } diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/protocol/processor/WebHookProcessorTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/protocol/processor/WebHookProcessorTest.java index a828d70a0f..a6f49c3886 100644 --- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/protocol/processor/WebHookProcessorTest.java +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/protocol/processor/WebHookProcessorTest.java @@ -32,13 +32,16 @@ import java.nio.charset.StandardCharsets; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; -import org.powermock.reflect.Whitebox; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; import io.cloudevents.CloudEvent; import io.cloudevents.core.data.BytesCloudEventData; @@ -50,46 +53,39 @@ import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpVersion; +@ExtendWith(MockitoExtension.class) public class WebHookProcessorTest { @Mock private transient HookConfigOperationManager hookConfigOperationManager; @Mock private transient WebHookMQProducer webHookMQProducer; - - private transient WebHookController controller = new WebHookController(); + @Spy + private transient ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor("webhook"); private transient ArgumentCaptor captor = ArgumentCaptor.forClass(CloudEvent.class); - @Before + @InjectMocks + private transient WebHookController controller = new WebHookController(); + + @BeforeEach public void init() throws Exception { - hookConfigOperationManager = Mockito.mock(HookConfigOperationManager.class); Mockito.when(hookConfigOperationManager.queryWebHookConfigById(any())).thenReturn(buildMockWebhookConfig()); - webHookMQProducer = Mockito.mock(WebHookMQProducer.class); Mockito.doNothing().when(webHookMQProducer).send(captor.capture(), any()); - ProtocolAdaptor protocolAdaptor = ProtocolPluginFactory.getProtocolAdaptor("webhook"); - - Whitebox.setInternalState(controller, HookConfigOperationManager.class, hookConfigOperationManager); - Whitebox.setInternalState(controller, WebHookMQProducer.class, webHookMQProducer); - Whitebox.setInternalState(controller, ProtocolAdaptor.class, protocolAdaptor); } @Test public void testHandler() { - try { - WebHookProcessor processor = new WebHookProcessor(); - processor.setWebHookController(controller); - processor.handler(buildMockWebhookRequest()); - - CloudEvent msgSendToMq = captor.getValue(); - Assert.assertNotNull(msgSendToMq); - Assert.assertTrue(StringUtils.isNoneBlank(msgSendToMq.getId())); - Assert.assertEquals("www.github.com", msgSendToMq.getSource().getPath()); - Assert.assertEquals("github.ForkEvent", msgSendToMq.getType()); - Assert.assertEquals(BytesCloudEventData.wrap("\"mock_data\":0".getBytes(StandardCharsets.UTF_8)), msgSendToMq.getData()); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } + WebHookProcessor processor = new WebHookProcessor(); + processor.setWebHookController(controller); + processor.handler(buildMockWebhookRequest()); + + CloudEvent msgSendToMq = captor.getValue(); + Assertions.assertNotNull(msgSendToMq); + Assertions.assertTrue(StringUtils.isNoneBlank(msgSendToMq.getId())); + Assertions.assertEquals("www.github.com", msgSendToMq.getSource().getPath()); + Assertions.assertEquals("github.ForkEvent", msgSendToMq.getType()); + Assertions.assertEquals(BytesCloudEventData.wrap("\"mock_data\":0".getBytes(StandardCharsets.UTF_8)), msgSendToMq.getData()); } private HttpRequest buildMockWebhookRequest() { @@ -107,10 +103,10 @@ private WebHookConfig buildMockWebhookConfig() { WebHookConfig config = new WebHookConfig(); config.setCallbackPath("/webhook/github/eventmesh/all"); config.setManufacturerName("github"); + config.setManufacturerDomain("www.github.com"); config.setManufacturerEventName("ForkEvent"); config.setContentType("application/json"); config.setSecret("secret"); - config.setCloudEventSource("github"); config.setCloudEventName("github-eventmesh"); config.setCloudEventIdGenerateMode("uuid"); return config; diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/BannerUtilTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/BannerUtilTest.java index 5834c61fd7..96dd4ec099 100644 --- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/BannerUtilTest.java +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/BannerUtilTest.java @@ -17,17 +17,13 @@ package org.apache.eventmesh.runtime.util; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class BannerUtilTest { @Test public void testGenerateBanner() { - try { - BannerUtil.generateBanner(); - } catch (Exception e) { - Assert.fail("BannerUtil.generateBanner() test failed"); - } + Assertions.assertDoesNotThrow(BannerUtil::generateBanner); } } 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 index 782ec9204b..16fb42a25f 100644 --- 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 @@ -38,8 +38,8 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.regex.Pattern; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import io.cloudevents.CloudEvent; import io.cloudevents.SpecVersion; @@ -57,52 +57,52 @@ 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()); + Assertions.assertTrue(Pattern.compile("\\d{17}").matcher(seq).matches()); + Assertions.assertEquals(17, seq.length()); } @Test public void testBuildMeshClientID() { String clientGroup = "clientGroup"; String clientID = EventMeshUtil.buildMeshClientID(clientGroup, "LS"); - Assert.assertTrue(clientID.contains(clientGroup)); + Assertions.assertTrue(clientID.contains(clientGroup)); } @Test public void testBuildMeshTcpClientID() { String clientSysId = "clientSysId"; String clientID = EventMeshUtil.buildMeshTcpClientID(clientSysId, "purpose", "meshCluster"); - Assert.assertTrue(clientID.contains(clientSysId)); + Assertions.assertTrue(clientID.contains(clientSysId)); } @Test public void testBuildClientGroup() { String systemId = "systemId"; String clientGroup = EventMeshUtil.buildClientGroup(systemId); - Assert.assertEquals(clientGroup, systemId); + Assertions.assertEquals(clientGroup, systemId); } @Test public void testStackTrace() { Throwable e = new EventMeshException("error"); String exception = EventMeshUtil.stackTrace(e); - Assert.assertTrue(exception.contains(e.getMessage())); + Assertions.assertTrue(exception.contains(e.getMessage())); exception = EventMeshUtil.stackTrace(null); - Assert.assertNull(exception); + Assertions.assertNull(exception); } @Test public void testCreateJsoner() { ObjectMapper mapper = EventMeshUtil.createJsoner(); - Assert.assertNotNull(mapper); + Assertions.assertNotNull(mapper); } @Test public void testPrintMqMessage() { EventMeshMessage meshMessage = new EventMeshMessage(); String result = EventMeshUtil.printMqMessage(meshMessage); - Assert.assertTrue(result.contains("Message")); + Assertions.assertTrue(result.contains("Message")); } @Test @@ -114,7 +114,7 @@ public void testGetMessageBizSeq() throws URISyntaxException { .withType(TYPE) .build(); String result = EventMeshUtil.getMessageBizSeq(cloudEvent); - Assert.assertEquals(result, value); + Assertions.assertEquals(result, value); } @Test @@ -126,20 +126,20 @@ public void testGetEventProp() throws URISyntaxException { .withType(TYPE) .build(); Map result = EventMeshUtil.getEventProp(cloudEvent); - Assert.assertEquals(result.get(EventMeshConstants.KEYS_LOWERCASE), value); + Assertions.assertEquals(result.get(EventMeshConstants.KEYS_LOWERCASE), value); } @Test public void testGetLocalAddr() { String addr = EventMeshUtil.getLocalAddr(); - Assert.assertNotNull(addr); + Assertions.assertNotNull(addr); } @Test public void testNormalizeHostAddress() throws UnknownHostException { InetAddress localAddress = InetAddress.getLocalHost(); String result = EventMeshUtil.normalizeHostAddress(localAddress); - Assert.assertNotNull(result); + Assertions.assertNotNull(result); } @Test @@ -151,29 +151,25 @@ public void testBuildUserAgentClientId() { 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)); + Assertions.assertEquals(result, String.format("%s--%d-%s:%d", subSystem, pid, host, port)); result = EventMeshUtil.buildUserAgentClientId(null); - Assert.assertNull(result); + Assertions.assertNull(result); } @Test public void testCloneObject() throws IOException, ClassNotFoundException { TopicMetadata topicMetadata = new TopicMetadata("topicName"); TopicMetadata topicMetadata2 = EventMeshUtil.cloneObject(topicMetadata); - Assert.assertNotEquals(System.identityHashCode(topicMetadata), System.identityHashCode(topicMetadata2)); - Assert.assertEquals(topicMetadata, topicMetadata2); + Assertions.assertNotEquals(System.identityHashCode(topicMetadata), System.identityHashCode(topicMetadata2)); + Assertions.assertEquals(topicMetadata, topicMetadata2); } @Test public void testPrintState() { - try { - ScheduledExecutorService serviceRebalanceScheduler = ThreadPoolFactory - .createScheduledExecutor(5, new EventMeshThreadFactory("proxy-rebalance-sch", true)); - EventMeshUtil.printState((ThreadPoolExecutor) serviceRebalanceScheduler); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } + ScheduledExecutorService serviceRebalanceScheduler = ThreadPoolFactory + .createScheduledExecutor(5, new EventMeshThreadFactory("proxy-rebalance-sch", true)); + Assertions.assertDoesNotThrow(() -> EventMeshUtil.printState((ThreadPoolExecutor) serviceRebalanceScheduler)); } @Test @@ -181,17 +177,17 @@ public void testGetCloudEventExtensionMap() { URI source = URI.create("uri"); CloudEventV03 cloudEventV03 = CloudEventBuilder.v03().withId(V03).withSource(source).withType(V03).build(); Map extMapV03 = EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V03.toString(), cloudEventV03); - Assert.assertNotNull(extMapV03); - Assert.assertEquals(V03, extMapV03.get("id")); - Assert.assertEquals(V03, extMapV03.get(TYPE)); + Assertions.assertNotNull(extMapV03); + Assertions.assertEquals(V03, extMapV03.get("id")); + Assertions.assertEquals(V03, extMapV03.get(TYPE)); CloudEventV1 cloudEventV1 = (CloudEventV1) CloudEventBuilder.v1().withId("V1").withSource(source).withType("V1").build(); Map extMapV1 = EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V1.toString(), cloudEventV1); - Assert.assertNotNull(extMapV1); - Assert.assertEquals("V1", extMapV1.get("id")); - Assert.assertEquals("V1", extMapV1.get(TYPE)); + Assertions.assertNotNull(extMapV1); + Assertions.assertEquals("V1", extMapV1.get("id")); + Assertions.assertEquals("V1", extMapV1.get(TYPE)); Map map = EventMeshUtil.getCloudEventExtensionMap(SpecVersion.V03.toString(), cloudEventV1); - Assert.assertTrue(map.isEmpty()); + Assertions.assertTrue(map.isEmpty()); } } diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/HttpResponseUtilsTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/HttpResponseUtilsTest.java index 585dd38af4..3a6d0bccc0 100644 --- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/HttpResponseUtilsTest.java +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/HttpResponseUtilsTest.java @@ -17,8 +17,8 @@ package org.apache.eventmesh.runtime.util; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; @@ -30,20 +30,20 @@ public class HttpResponseUtilsTest { @Test public void testCreateSuccess() { - Assert.assertEquals(HttpVersion.HTTP_1_1, HttpResponseUtils.createSuccess().protocolVersion()); - Assert.assertEquals(HttpResponseStatus.OK, HttpResponseUtils.createSuccess().status()); + Assertions.assertEquals(HttpVersion.HTTP_1_1, HttpResponseUtils.createSuccess().protocolVersion()); + Assertions.assertEquals(HttpResponseStatus.OK, HttpResponseUtils.createSuccess().status()); } @Test public void testCreateNotFound() { - Assert.assertEquals(HttpVersion.HTTP_1_1, HttpResponseUtils.createNotFound().protocolVersion()); - Assert.assertEquals(HttpResponseStatus.NOT_FOUND, HttpResponseUtils.createNotFound().status()); + Assertions.assertEquals(HttpVersion.HTTP_1_1, HttpResponseUtils.createNotFound().protocolVersion()); + Assertions.assertEquals(HttpResponseStatus.NOT_FOUND, HttpResponseUtils.createNotFound().status()); } @Test public void testCreateInternalServerError() { - Assert.assertEquals(HttpVersion.HTTP_1_1, HttpResponseUtils.createInternalServerError().protocolVersion()); - Assert.assertEquals(HttpResponseStatus.INTERNAL_SERVER_ERROR, HttpResponseUtils.createInternalServerError().status()); + Assertions.assertEquals(HttpVersion.HTTP_1_1, HttpResponseUtils.createInternalServerError().protocolVersion()); + Assertions.assertEquals(HttpResponseStatus.INTERNAL_SERVER_ERROR, HttpResponseUtils.createInternalServerError().status()); } } 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 index 8a63344840..30c2e65a68 100644 --- 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 @@ -30,8 +30,8 @@ import java.util.ArrayList; import java.util.List; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.mockito.Mockito; @@ -44,8 +44,8 @@ public void testHttpGet() throws IOException { dummyStatic.when(() -> IOUtils.toString(any(InputStream.class), any(String.class))).thenReturn(content); String requestUrl = "https://eventmesh.apache.org"; HttpResult result = HttpTinyClient.httpGet(requestUrl, null, null, "utf-8", 0); - Assert.assertEquals(content, result.getContent()); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assertions.assertEquals(content, result.getContent()); + Assertions.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); } List paramValues = new ArrayList<>(); @@ -60,8 +60,8 @@ public void testHttpGet() throws IOException { dummyStatic.when(() -> IOUtils.toString(any(InputStream.class), any(String.class))).thenReturn(content); String requestUrl = "https://eventmesh.apache.org"; HttpResult result = HttpTinyClient.httpGet(requestUrl, headers, paramValues, "utf-8", 0); - Assert.assertEquals(content, result.getContent()); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assertions.assertEquals(content, result.getContent()); + Assertions.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); } } @@ -72,8 +72,8 @@ public void testHttpPost() throws IOException { dummyStatic.when(() -> IOUtils.toString(any(InputStream.class), any(String.class))).thenReturn(content); String requestUrl = "https://eventmesh.apache.org"; HttpResult result = HttpTinyClient.httpPost(requestUrl, anyList(), anyList(), "utf-8", 0); - Assert.assertEquals(content, result.getContent()); - Assert.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); + Assertions.assertEquals(content, result.getContent()); + Assertions.assertEquals(HttpURLConnection.HTTP_OK, result.getCode()); } } } 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 index 8258d386f3..7f0cacc683 100644 --- 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 @@ -20,8 +20,8 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import io.netty.channel.Channel; @@ -31,15 +31,15 @@ public class RemotingHelperTest { @Test public void testExceptionSimpleDesc() { String result = RemotingHelper.exceptionSimpleDesc(new NullPointerException()); - Assert.assertNotNull(result); + Assertions.assertNotNull(result); } @Test public void testString2SocketAddress() { String addr = "10.1.1.1:11002"; InetSocketAddress address = (InetSocketAddress) RemotingHelper.string2SocketAddress(addr); - Assert.assertNotNull(address); - Assert.assertEquals("10.1.1.1:11002", address.getHostString() + ":" + address.getPort()); + Assertions.assertNotNull(address); + Assertions.assertEquals("10.1.1.1:11002", address.getHostString() + ":" + address.getPort()); } @Test @@ -48,13 +48,13 @@ public void testParseChannelRemoteAddr() { 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"); + Assertions.assertEquals(addr, "127.0.0.1:80"); } @Test public void testParseSocketAddressAddr() { InetSocketAddress address = new InetSocketAddress("localhost", 80); String addr = RemotingHelper.parseSocketAddressAddr(address); - Assert.assertEquals("127.0.0.1:80", addr); + Assertions.assertEquals("127.0.0.1:80", addr); } -} \ No newline at end of file +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ServerGlobalTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ServerGlobalTest.java index 740da13d70..6e51012f62 100644 --- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ServerGlobalTest.java +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ServerGlobalTest.java @@ -19,8 +19,8 @@ import java.util.concurrent.atomic.AtomicLong; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; /** * ServerGlobal test cases. @@ -30,12 +30,12 @@ public class ServerGlobalTest { @Test public void testGetMsgCounter() { ServerGlobal.getInstance().setMsgCounter(new AtomicLong(1L)); - Assert.assertEquals(1L, ServerGlobal.getInstance().getMsgCounter().get()); + Assertions.assertEquals(1L, ServerGlobal.getInstance().getMsgCounter().get()); } @Test public void testSetMsgCounter() { ServerGlobal.getInstance().setMsgCounter(new AtomicLong(1L)); - Assert.assertEquals(1L, ServerGlobal.getInstance().getMsgCounter().get()); + Assertions.assertEquals(1L, ServerGlobal.getInstance().getMsgCounter().get()); } -} \ No newline at end of file +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ThreadPoolHelperTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ThreadPoolHelperTest.java new file mode 100644 index 0000000000..d04712eef4 --- /dev/null +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ThreadPoolHelperTest.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.runtime.util; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class ThreadPoolHelperTest { + + @Mock + private ThreadPoolExecutor mockThreadPool; + + @Mock + private RejectedExecutionHandler mockRejectionPolicy; + + @Test + public void testPrintState() { + when(mockThreadPool.isShutdown()).thenReturn(false); + when(mockThreadPool.isTerminating()).thenReturn(false); + when(mockThreadPool.isTerminated()).thenReturn(false); + when(mockThreadPool.getActiveCount()).thenReturn(2); + when(mockThreadPool.getCompletedTaskCount()).thenReturn(10L); + when(mockThreadPool.getTaskCount()).thenReturn(15L); + when(mockThreadPool.getQueue()).thenReturn(new LinkedBlockingDeque<>(5)); + when(mockThreadPool.getCorePoolSize()).thenReturn(5); + when(mockThreadPool.getMaximumPoolSize()).thenReturn(10); + when(mockThreadPool.getKeepAliveTime(any(TimeUnit.class))).thenReturn(1000L); + when(mockThreadPool.getRejectedExecutionHandler()).thenReturn(mockRejectionPolicy); + + ThreadPoolHelper.printState(mockThreadPool); + + verify(mockThreadPool).isShutdown(); + verify(mockThreadPool).isTerminating(); + verify(mockThreadPool).isTerminated(); + verify(mockThreadPool).getActiveCount(); + verify(mockThreadPool).getCompletedTaskCount(); + verify(mockThreadPool).getTaskCount(); + verify(mockThreadPool).getQueue(); + verify(mockThreadPool).getCorePoolSize(); + verify(mockThreadPool).getMaximumPoolSize(); + verify(mockThreadPool).getKeepAliveTime(any(TimeUnit.class)); + verify(mockThreadPool).getRejectedExecutionHandler(); + } +} diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ValueComparatorTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ValueComparatorTest.java index 7e64083022..e647a52152 100644 --- a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ValueComparatorTest.java +++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/util/ValueComparatorTest.java @@ -24,19 +24,17 @@ import java.util.Map; import java.util.TreeMap; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class ValueComparatorTest { @Test - public void testSerializeOrderedCollection() { + public void testSerializeOrderedCollection() throws IOException { Map, Integer> map = new TreeMap<>(new ValueComparator()); try (OutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos)) { - oos.writeObject(map); - } catch (IOException e) { - Assert.fail(); + Assertions.assertDoesNotThrow(() -> oos.writeObject(map)); } } 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 index 8fe6159716..777467e9a9 100644 --- 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 @@ -32,15 +32,15 @@ import java.util.HashMap; import java.util.Map; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.mockito.Mockito; public class WebhookUtilTest { @Test - public void testObtainDeliveryAgreement() { + public void testObtainDeliveryAgreement() throws Exception { // normal case try (CloseableHttpClient httpClient = mock(CloseableHttpClient.class); CloseableHttpResponse response = mock(CloseableHttpResponse.class); @@ -49,20 +49,25 @@ public void testObtainDeliveryAgreement() { Mockito.when(response.getLastHeader("WebHook-Allowed-Origin")) .thenReturn(new BasicHeader("WebHook-Allowed-Origin", "*")); Mockito.when(httpClient.execute(any())).thenReturn(response); - Assert.assertTrue("match logic must return true", - WebhookUtil.obtainDeliveryAgreement(httpClient, "https://eventmesh.apache.org", "*")); + Assertions.assertTrue(WebhookUtil.obtainDeliveryAgreement(httpClient, "https://eventmesh.apache.org", "*"), + "match logic must return true"); // abnormal case Mockito.when(httpClient2.execute(any())).thenThrow(new RuntimeException()); - try { - Assert.assertTrue("when throw exception ,default return true", - WebhookUtil.obtainDeliveryAgreement(httpClient2, "xxx", "*")); - } catch (RuntimeException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertTrue(WebhookUtil.obtainDeliveryAgreement(httpClient2, "https://eventmesh.apache.org", "*"), + "when throw exception ,default return true"); + } + } - } catch (Exception e) { - Assert.fail(e.getMessage()); + @Test + public void testObtainDeliveryAgreementWithInvalidTargetUrl() throws Exception { + try (CloseableHttpClient httpClient = mock(CloseableHttpClient.class); + CloseableHttpResponse response = mock(CloseableHttpResponse.class)) { + Mockito.when(response.getLastHeader("WebHook-Allowed-Origin")) + .thenReturn(new BasicHeader("WebHook-Allowed-Origin", "*")); + Mockito.when(httpClient.execute(any())).thenReturn(response); + Assertions.assertFalse(WebhookUtil.obtainDeliveryAgreement(httpClient, "ftp://eventmesh.apache.org", "*"), + "when target url is invalid, return false"); } } @@ -81,7 +86,7 @@ public void testSetWebhookHeaders() { dummyStatic.when(() -> EventMeshExtensionFactory.getExtension(AuthService.class, authType)).thenReturn(authService); final HttpPost post = new HttpPost(); WebhookUtil.setWebhookHeaders(post, "application/json", "eventmesh.FT", authType); - Assert.assertEquals("match expect value", post.getLastHeader(key).getValue(), value); + Assertions.assertEquals(post.getLastHeader(key).getValue(), value, "match expect value"); } } } diff --git a/eventmesh-runtime/src/test/resources/configuration.properties b/eventmesh-runtime/src/test/resources/configuration.properties index ef3fe92666..71ad34e19f 100644 --- a/eventmesh-runtime/src/test/resources/configuration.properties +++ b/eventmesh-runtime/src/test/resources/configuration.properties @@ -25,20 +25,21 @@ eventMesh.server.hostIp=hostIp-succeed!!! eventMesh.connector.plugin.type=connector-succeed!!! eventMesh.storage.plugin.type=storage-succeed!!! eventMesh.security.plugin.type=security-succeed!!! -eventMesh.registry.plugin.type=registry-succeed!!! eventMesh.trace.plugin=trace-succeed!!! -eventMesh.server.registry.registerIntervalInMills=816 -eventMesh.server.registry.fetchRegistryAddrIntervalInMills=1816 + eventMesh.metrics.plugin=metrics-succeed1!!!,metrics-succeed2!!!,metrics-succeed3!!! -eventMesh.registry.plugin.server-addr=server-addr-succeed1!!! +eventMesh.metaStorage.plugin.type=metaStorage-succeed!!! +eventMesh.metaStorage.plugin.server-addr=server-addr-succeed1!!! +eventMesh.metaStorage.plugin.enabled=true +eventMesh.metaStorage.plugin.username=username-succeed!!! +eventMesh.metaStorage.plugin.password=password-succeed!!! +eventMesh.metaStorage.plugin.registerIntervalInMills=816 +eventMesh.metaStorage.plugin.fetchRegistryAddrIntervalInMills=1816 eventMesh.server.security.enabled=true -eventMesh.server.registry.enabled=true eventMesh.server.trace.enabled=true eventMesh.server.provide.protocols=TCP,HTTP,GRPC -eventMesh.registry.plugin.username=username-succeed!!! -eventMesh.registry.plugin.password=password-succeed!!! # EventMeshHTTPConfiguration config eventMesh.server.http.port=1816 @@ -48,10 +49,10 @@ eventMesh.server.sendmsg.threads.num=3816 eventMesh.server.pushmsg.threads.num=4816 eventMesh.server.replymsg.threads.num=5816 eventMesh.server.clientmanage.threads.num=6816 -eventMesh.server.registry.threads.num=7816 +eventMesh.server.metaStorage.threads.num=7816 eventMesh.server.admin.threads.num=8816 eventMesh.server.retry.threads.num=9816 -eventMesh.server.pull.registry.interval=11816 +eventMesh.server.pull.metaStorage.interval=11816 eventMesh.server.async.accumulation.threshold=12816 eventMesh.server.retry.blockQ.size=13816 eventMesh.server.batchmsg.blockQ.size=14816 diff --git a/eventmesh-sdks/eventmesh-sdk-c/README.md b/eventmesh-sdks/eventmesh-sdk-c/README.md new file mode 100644 index 0000000000..25a4ddabea --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/README.md @@ -0,0 +1,20 @@ +## EventMesh C/C++ SDK + +### Support api + +1. **TCP** + +### Build +1. **build lib** +``` +git submodule init +git submodule update +make +``` + +2. **build example** +``` +git submodule init +git submodule update +make demo +``` \ No newline at end of file diff --git a/eventmesh-sdks/eventmesh-sdk-c/configs/rmb.conf b/eventmesh-sdks/eventmesh-sdk-c/configs/rmb.conf new file mode 100644 index 0000000000..b30682f8ff --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/configs/rmb.conf @@ -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. + +consumerSysId 1000 +consumerSysVersion 1.0.0 +consumerSvrId 10.199.199.199 +consumerDcn A00 +orgId 99996 +localIdc A +wemq_user wemq +wemq_passwd wemq@123 + +#log configure +logFile sub +logLevel 5 +logFileNums 10 +logFileSize 100000000 +logSwiftType 1 + +#receive message +reqFifoPath ./tmp_req.fifo +reqShmKey 0x27151203 +reqShmSize 20000000 +#receive rr-async reply message +ayncRspFifoPath ./tmp_aync_rsp.fifo +ayncRspShmKey 0x77151204 +ayncRspShmSize 20000000 +#receive broadcast message +broadcastFifoPath ./tmp_broadcast.fifo +broadcastShmKey 0x77151205 +broadcastShmSize 20000000 + +#message log control +logserverSwitch 0 +#req gsl +ReqGslSwitch 0 + +#wemq cc configure +wemqUseHttpCfg 1 +configCenterIp 10.255.34.57 +configCenterPort 8090 +configCenterAddrMulti 172.22.1.82:8090 +#connect directly to access when: wemqUseHttpCfg 0 +wemqProxyIp 172.22.0.51 +wemqProxyPort 10000 +# tlsOnoff:控制与eventmesh的tcp连接是否开启tls +# 0: 不开启(默认) +# 1: 开启 +tlsOnoff 0 diff --git a/eventmesh-sdks/eventmesh-sdk-c/examples/demo.c b/eventmesh-sdks/eventmesh-sdk-c/examples/demo.c new file mode 100644 index 0000000000..f6b7f4f55a --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/examples/demo.c @@ -0,0 +1,1715 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rmb_sub.h" +#include "rmb_pub.h" +#include "rmb_msg.h" +#include "rmb_udp.h" +#include "rmb_cfg.h" +#include "rmb_log.h" +#include "rmb_errno.h" + +#define LOG_PRINT(loglevel,fmt, args...) {log_print(loglevel, "[%s:%d(%s)]: "fmt"", __FILE__, __LINE__, __FUNCTION__, ## args);} + +#define UNIX_DOMAIN "unix.domain" + +typedef struct tMessage +{ + int type; //0:pub 1:sub + pid_t pid; + unsigned int process_num; + unsigned int process_status; + unsigned int has_send; + unsigned int send_msg_num; + unsigned int recv_msg_num; +} tMessage; + +#define MAX_MSG_LEN (1024*1024*3+1) + +static const char *version_test = "RMB_C_API_V2.2.0"; + +static const char *send_msg = "pubSendMsg"; + +pthread_mutex_t test_mutex; + +StRmbSub *pRmbSub; +StRmbPub *pRmbPub; + +static char StatLogLevel[6][10] = + { "FATAL", "ERROR", "WARN ", "INFO", "DEBUG", "ALL" }; + +int log_print (int logLevel, const char *format, ...) +{ + va_list ap; + struct timeval stLogTv; + + va_start (ap, format); + gettimeofday (&stLogTv, NULL); + fprintf (stdout, "[%s][%s %03d][%d]", StatLogLevel[logLevel], + RmbGetDateTimeStr ((const time_t *) &(stLogTv.tv_sec)), + (int) ((stLogTv.tv_usec) / 1000), getpid ()); + //fprintf(stdout, "[%s][%d]", StatLogLevel[logLevel],getpid()); + vfprintf (stdout, format, ap); + va_end (ap); + fprintf (stdout, "\n"); + + return 0; +} + +void printfUsage (const char *name) +{ + printf ("%s: version:%s\n\n", name, version_test); + + printf ("%s: sub server端(非广播)\n", name); + printf + (" %s sub sleep_time log_control process_nums topic1 topic2 ...\n", + name); + printf + (" sleep_time:睡眠时间,通常为0, log_control:测试内容大小时使用,1:打印,其他值为不打印 process_nums:进程数量,最小为1\n"); + printf ("\n"); + + printf ("%s: sub server端(广播)\n", name); + printf + (" %s sub_broadcast process_nums log_control topic1 topic2 ...\n", name); + printf ("\n"); + + printf + ("%s: pub client端(RR同步消息/单播/多播/广播消息发送):\n", + name); + printf + (" %s pub pthread_nums log_control msg_nums msg_len ttl_time sleep_time topic1 topic2 ...\n", + name); + printf + (" pthread_nums:线程数量,最小为1, log_control:测试内容大小时使用,1:打印,其他值为不打印 msg_nums:每个线程发送消息数量 msg:消息内容 msg_len:消息内容大小\n"); + printf ("\n"); + + printf ("%s: pub端(RR异步):\n", name); + printf + (" %s rr_async_pub process_nums log_control msg_nums msg_len sleep_time topic\n", + name); + printf + (" process_nums:进程数量,最小为1, msg_nums:每个进程发送消息数量 msg:消息内容\n"); + printf ("\n"); + + printf ("////////////////////////////////////////////////////////\n"); + + exit (0); +} + +typedef struct StDemoArgv +{ + //建议字段 + StRmbPub *pRmbPub; + StRmbSub *pRmbSub; + StRmbMsg *pReceiveMsg; + StRmbMsg *pReplyMsg; + //其他字段 + unsigned int uiLog; + unsigned long ulMsgTotal; + unsigned int uiSleepTime; + unsigned int uiLogServer; + unsigned int uiFlag; +} StDemoArgv; + +typedef struct tThreadArgs +{ + StRmbPub *pRmbPub; + enum EVENT_OR_SERVICE_CALL event_or_service; + unsigned int times; + int iContent; + char cDcn[100]; + char cServiceId[100]; + char cSenaId[100]; + /////////////// + unsigned long ulMsgSucc; + /////////////// + int iLogNum; + unsigned long ttl; + const char *pMsg; +} tThreadArgs; + +/** + * return value: + * 0: success + * 1: topic check failed + * <0: send error + */ +int pubOwnMessage (StRmbPub * pRmbPub, int iEventOrService, + unsigned long ttl_time, const char *cDcn, + const char *cServiceId, const char *cSenaId, + unsigned int log_control, const char *strMsg) +{ + int iRet = 0; + StRmbMsg *pSendMsg = rmb_msg_malloc (); + rmb_msg_clear (pSendMsg); + static unsigned int uiSeq = 1; + struct timeval tv; + gettimeofday (&tv, NULL); + unsigned long ulNowTime = tv.tv_sec * 1000 + tv.tv_usec / 1000; + char cSeqNo[33]; + snprintf (cSeqNo, sizeof (cSeqNo), "%013lu%019u", ulNowTime, uiSeq++); +// rmb_msg_set_bizSeqNo(pSendMsg, "12345678901234567890123456789012"); + rmb_msg_set_bizSeqNo (pSendMsg, cSeqNo); +// rmb_msg_set_consumerSeqNo(pSendMsg, "22222678901234567890123456799999"); + rmb_msg_set_consumerSeqNo (pSendMsg, cSeqNo); + rmb_msg_set_orgSysId (pSendMsg, "9999"); + //set ttl, millisecond(hao s) +// printf("ttl = %lu\n", ttl_time); + if (ttl_time > 0) + { + rmb_msg_set_live_time (pSendMsg, ttl_time); + } + if (iEventOrService == 0) + { + iRet = + rmb_msg_set_dest (pSendMsg, RMB_DEST_TOPIC, cDcn, RMB_EVENT_CALL, + cServiceId, cSenaId); + } + else + { + iRet = + rmb_msg_set_dest (pSendMsg, RMB_DEST_TOPIC, cDcn, RMB_SERVICE_CALL, + cServiceId, cSenaId); + } +/* if (iRet < 0) + return 1;*/ + + rmb_msg_set_content (pSendMsg, strMsg, strlen (strMsg)); + char appHeader[100] = "{}"; + rmb_msg_set_app_header (pSendMsg, appHeader, strlen (appHeader)); + + if (iEventOrService == 0) + { + iRet = rmb_pub_send_msg (pRmbPub, pSendMsg); + if (log_control & 2) + { + if (iRet == 0) + { + LOG_PRINT (RMB_LOG_INFO, "send msg=%s OK", pSendMsg->cContent); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_send_msg error!iRet = %d", iRet); + } + } + } + else + { + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + iRet = rmb_pub_send_and_receive (pRmbPub, pSendMsg, pReceiveMsg, 50000); + if (iRet == 0) + { + char receiveBuf[MAX_MSG_LEN]; + unsigned int receiveLen = sizeof (receiveBuf); + rmb_msg_get_content (pReceiveMsg, receiveBuf, &receiveLen); + + if (log_control == 1) + { + LOG_PRINT (RMB_LOG_INFO, "receive reply:len=%u, %s", receiveLen, + receiveBuf); + } + } + else + { + LOG_PRINT (RMB_LOG_INFO, + "rmb_pub_send_and_receive error!iRet = %d,msg=%s", iRet, + strMsg); + } + + //sleep(1); + rmb_msg_free (pReceiveMsg); + } + + rmb_msg_free (pSendMsg); + return iRet; +} + +////////////////////////////////////////////////// + +int pub_message (StRmbPub * pRmbPub, int iEventOrService, int first_msg_nums, + int second_msg_nums, const char *cDcn, + const char *cServiceId, const char *cSenaId) +{ + int iRet = 0; + StRmbMsg *pSendMsg = rmb_msg_malloc (); + + rmb_msg_set_bizSeqNo (pSendMsg, "12345678901234567890123456789012"); + rmb_msg_set_consumerSeqNo (pSendMsg, "22222678901234567890123456799999"); + rmb_msg_set_orgSysId (pSendMsg, "9999"); + if (iEventOrService == 0) + { + rmb_msg_set_dest (pSendMsg, RMB_DEST_TOPIC, cDcn, RMB_EVENT_CALL, + cServiceId, cSenaId); + } + else + { + rmb_msg_set_dest (pSendMsg, RMB_DEST_TOPIC, cDcn, RMB_SERVICE_CALL, + cServiceId, cSenaId); + } + rmb_msg_set_content (pSendMsg, send_msg, strlen (send_msg)); + char appHeader[100] = "{}"; + rmb_msg_set_app_header (pSendMsg, appHeader, strlen (appHeader)); + + unsigned long ulNowTime = 0; + unsigned long ulSleepTime = 0; + struct timeval tv; + + if (iEventOrService == 0) + { + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + int i; + for (i = 0; i < first_msg_nums; i++) + { + iRet = rmb_pub_send_msg (pRmbPub, pSendMsg); +#ifdef DEBUG + if (iRet == 0) + { + LOG_PRINT (RMB_LOG_INFO, "send msg=%s OK", pSendMsg->cContent); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_send_msg error!iRet = %d", iRet); + } +#endif + } + + gettimeofday (&tv, NULL); + ulSleepTime = tv.tv_sec * 1000000 + tv.tv_usec - ulNowTime; + printf ("ulSleepTime = %lu\n", ulSleepTime); + if (ulSleepTime < 1000000) + usleep (ulSleepTime); + + for (i = 0; i < second_msg_nums; i++) + { + iRet = rmb_pub_send_msg (pRmbPub, pSendMsg); +#ifdef DEBUG + if (iRet == 0) + { + LOG_PRINT (RMB_LOG_INFO, "send msg=%s OK", pSendMsg->cContent); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_send_msg error!iRet = %d", iRet); + } +#endif + } + } + else + { + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + int i; + for (i = 0; i < first_msg_nums; i++) + { + iRet = rmb_pub_send_and_receive (pRmbPub, pSendMsg, pReceiveMsg, 5000); + if (iRet == 0) + { + char receiveBuf[1024]; + unsigned int receiveLen = sizeof (receiveBuf); + rmb_msg_get_content (pReceiveMsg, receiveBuf, &receiveLen); +#ifdef DEBUG + LOG_PRINT (RMB_LOG_INFO, "receive reply pkg=%s", receiveBuf); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, + "rmb_pub_send_and_receive error!iRet = %d,msg=%s", iRet, + strMsg); + } +#else + } +#endif + } + gettimeofday (&tv, NULL); + ulSleepTime = tv.tv_sec * 1000000 + tv.tv_usec - ulNowTime; + printf ("ulSleepTime = %lu\n", ulSleepTime); + if (ulSleepTime < 1000000) + usleep (ulSleepTime); + + for (i = 0; i < second_msg_nums; i++) + { + iRet = rmb_pub_send_and_receive (pRmbPub, pSendMsg, pReceiveMsg, 5000); + if (iRet == 0) + { + char receiveBuf[1024]; + unsigned int receiveLen = sizeof (receiveBuf); + rmb_msg_get_content (pReceiveMsg, receiveBuf, &receiveLen); +#ifdef DEBUG + LOG_PRINT (RMB_LOG_INFO, "receive reply pkg=%s", receiveBuf); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, + "rmb_pub_send_and_receive error!iRet = %d,msg=%s", iRet, + strMsg); + } +#else + } +#endif + } + + rmb_msg_free (pReceiveMsg); + } + printf ("%s: send msg:%d\n", __func__, first_msg_nums + second_msg_nums); + + rmb_msg_free (pSendMsg); + return iRet; +} + +static int pub_board_message (StRmbPub * pRmbPub, int iEventOrService, + unsigned long ttl_time, const char *cDcn, + const char *cServiceId, const char *cSenaId, + const char *cOrgId, unsigned int log_control, + const char *strMsg) +{ + int iRet = 0; + StRmbMsg *pSendMsg = rmb_msg_malloc (); + rmb_msg_clear (pSendMsg); + rmb_msg_set_bizSeqNo (pSendMsg, "12345678901234567890123456789012"); + rmb_msg_set_consumerSeqNo (pSendMsg, "22222678901234567890123456799999"); + rmb_msg_set_orgSysId (pSendMsg, "9999"); + //set ttl, millisecond(hao s) + //printf("ttl = %lu\n", ttl_time); + if (ttl_time > 0) + rmb_msg_set_live_time (pSendMsg, ttl_time); + + if (iEventOrService != RMB_EVENT_CALL) + { + printf ("type:%d is not event call\n", iEventOrService); + return -1; + } + + iRet = rmb_msg_set_dest_v2_1 (pRmbPub, cDcn, cServiceId, cSenaId, cOrgId); + if (iRet < 0) + { + printf ("rmb_msg_set_dest_v2_1 return: %d\n", iRet); + return iRet; + } + + rmb_msg_set_content (pSendMsg, strMsg, strlen (strMsg)); + char appHeader[100] = "{}"; + rmb_msg_set_app_header (pSendMsg, appHeader, strlen (appHeader)); + if (iEventOrService == 0) + { + iRet = rmb_pub_send_msg (pRmbPub, pSendMsg); + if (log_control & 2) + { + if (iRet == 0) + { + LOG_PRINT (RMB_LOG_INFO, "send msg=%s OK", pSendMsg->cContent); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_send_msg error!iRet = %d", iRet); + } + } + } + + rmb_msg_free (pSendMsg); + return iRet; +} + +int mutil_thread_pub_message (StRmbPub * pRmbPub, int iEventOrService, + unsigned long ttl, int iContentBase, + int iOffset, const char *cDcn, + const char *cServiceId, const char *cSenaId, + const char *strMsg) +{ + int iRet = 0; + StRmbMsg *pSendMsg = rmb_msg_malloc (); + + rmb_msg_set_bizSeqNo (pSendMsg, "12345678901234567890123456789012"); + rmb_msg_set_consumerSeqNo (pSendMsg, "22222678901234567890123456799999"); + rmb_msg_set_orgSysId (pSendMsg, "9999"); +// printf("ttl = %lu\n", ttl); + if (ttl > 0) + { + rmb_msg_set_live_time (pSendMsg, ttl); + } + if (iEventOrService == 0) + { + rmb_msg_set_dest (pSendMsg, RMB_DEST_TOPIC, cDcn, RMB_EVENT_CALL, + cServiceId, cSenaId); + } + else + { + rmb_msg_set_dest (pSendMsg, RMB_DEST_TOPIC, cDcn, RMB_SERVICE_CALL, + cServiceId, cSenaId); + } + +// char cContent[100]; +// snprintf(cContent, sizeof(cContent), "thread%d--%dth:%s", iContentBase, iOffset, strMsg); +// rmb_msg_set_content(pSendMsg, cContent, strlen(cContent)); + rmb_msg_set_content (pSendMsg, strMsg, strlen (strMsg)); + char appHeader[100] = "{}"; + rmb_msg_set_app_header (pSendMsg, appHeader, strlen (appHeader)); + + if (iEventOrService == 0) + { + iRet = rmb_pub_send_msg (pRmbPub, pSendMsg); +#ifdef DEBUG + if (iRet == 0) + { + LOG_PRINT (RMB_LOG_INFO, "send msg=%s OK", pSendMsg->cContent); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_send_msg error!iRet = %d", iRet); + } +#endif + } + else + { + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + iRet = rmb_pub_send_and_receive (pRmbPub, pSendMsg, pReceiveMsg, 5000); + if (iRet == 0) + { +// char receiveBuf[1024]; + char receiveBuf[MAX_MSG_LEN]; + unsigned int receiveLen = sizeof (receiveBuf); + rmb_msg_get_content (pReceiveMsg, receiveBuf, &receiveLen); +#ifdef DEBUG + LOG_PRINT (RMB_LOG_INFO, "receive reply pkg=%s", receiveBuf); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, + "rmb_pub_send_and_receive error!iRet = %d,msg=%s", iRet, + strMsg); + } +#else + } +#endif + rmb_msg_free (pReceiveMsg); + } + + rmb_msg_free (pSendMsg); + return iRet; +} + +void mutil_thread_for_pub (void *pArgs) +{ + tThreadArgs *pTmp = (tThreadArgs *) pArgs; + + int iRet = 0; + unsigned int message_times = 0; + int i; + for (i = 0; i < pTmp->times; ++i) + { + iRet = + mutil_thread_pub_message (pTmp->pRmbPub, pTmp->event_or_service, + pTmp->ttl, pTmp->iContent, i, pTmp->cDcn, + pTmp->cServiceId, pTmp->cSenaId, pTmp->pMsg); + if (iRet == 0) + { + message_times++; + pTmp->ulMsgSucc++; + } + } + if (pTmp->event_or_service == RMB_SERVICE_CALL) + { + LOG_PRINT (RMB_LOG_INFO, "threadid:%d -- pub send %u and recv msg:%u\n", + (int) pthread_self (), pTmp->times, message_times); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, "threadid:%d -- pub send %u and succ msg:%u\n", + (int) pthread_self (), pTmp->times, message_times); + } +} + +//sub回调函数 +void func_with_req (const char *buf, const int len, void *pAgv) +//void func_with_req(void *pRevMsg, void *pAgv) +{ + if (pAgv == NULL) + { + printf ("%s:%d-%s pAgv or pRevMsg is null\n", __FILE__, __LINE__, + __func__); + return; + } + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + if (pReceiveMsg == NULL) + { + printf ("rmb_msg_malloc failed"); + return; + } + + StDemoArgv *p = (StDemoArgv *) pAgv; + + shift_buf_2_msg (pReceiveMsg, buf, len); + + if (p->uiSleepTime > 0) + sleep (p->uiSleepTime); + +// //test for get dest +// const char *pDest = NULL; +// if ((pDest = rmb_msg_get_dest_ptr(pReceiveMsg)) != NULL) { +// printf("get dest name is:%s\n", pDest); +// } +// +// //test for get ConsumerSysId +// const char *pConsumerSysId = NULL; +// if ((pConsumerSysId = rmb_msg_get_consumerSysId_ptr(pReceiveMsg)) != NULL) { +// printf("get consumer sys id is:%s\n", pConsumerSysId); +// } +// +// //test for get cConsumerSvrId +// const char *pConsumerSvrId = NULL; +// if ((pConsumerSvrId = rmb_msg_get_consumerSvrId_ptr(pReceiveMsg)) != NULL) { +// printf("get consumer svr id is:%s\n", pConsumerSvrId); +// } +// +// printf("get consumerSysVersion version:%s\n", pReceiveMsg->sysHeader.cConsumerSysVersion); + +// printf("ulTranTimeStamp=%lu\n", pReceiveMsg->sysHeader.ulTranTimeStamp); + + p->uiFlag = 1; + p->ulMsgTotal++; + const char *pContent = NULL; + unsigned int uiContentLen = 0; + if ((pContent = + rmb_msg_get_content_ptr (pReceiveMsg, &uiContentLen)) != NULL) + { + if (p->uiLog == 1) + { + printf ("***get message len=%d,%s\n", uiContentLen, pContent); + } +// if (pReceiveMsg->iEventOrService == RMB_EVENT_CALL) { + if (strlen (pReceiveMsg->replyTo.cDestName) > 0) + { + char replyContent[MAX_MSG_LEN] = { 0 }; + unsigned int uiReplyLen = 0; + memcpy (replyContent, pContent, uiContentLen); + uiReplyLen += uiContentLen; + memcpy (&replyContent[uiReplyLen], "_reply", strlen ("_reply")); + uiReplyLen += strlen ("_reply"); + replyContent[uiReplyLen] = '\0'; + + rmb_msg_set_content (p->pReplyMsg, replyContent, uiReplyLen); + + char appHeader[10] = "{}"; + rmb_msg_set_app_header (p->pReplyMsg, appHeader, strlen (appHeader)); + rmb_sub_reply_msg (p->pRmbSub, pReceiveMsg, p->pReplyMsg); + } + rmb_sub_ack_msg (p->pRmbSub, pReceiveMsg); + } + + rmb_msg_free (pReceiveMsg); + + return; +} + +//sub回调函数 +void func_with_req_pub_reply (const char *buf, const int len, void *pAgv) +{ + if (pAgv == NULL) + { + printf ("%s:%d-%s pAgv or pRevMsg is null\n", __FILE__, __LINE__, + __func__); + return; + } + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + if (pReceiveMsg == NULL) + { + printf ("rmb_msg_malloc failed"); + return; + } + + StDemoArgv *p = (StDemoArgv *) pAgv; + + shift_buf_2_msg (pReceiveMsg, buf, len); + + //test for get dest + const char *pDest = NULL; + if ((pDest = rmb_msg_get_dest_ptr (pReceiveMsg)) != NULL) + { + printf ("get dest name is:%s\n", pDest); + } + + //test for get ConsumerSysId + const char *pConsumerSysId = NULL; + if ((pConsumerSysId = rmb_msg_get_consumerSysId_ptr (pReceiveMsg)) != NULL) + { + printf ("get consumer sys id is:%s\n", pConsumerSysId); + } + + //test for get cConsumerSvrId + const char *pConsumerSvrId = NULL; + if ((pConsumerSvrId = rmb_msg_get_consumerSvrId_ptr (pReceiveMsg)) != NULL) + { + printf ("get consumer svr id is:%s\n", pConsumerSvrId); + } + + printf ("get consumerSysVersion version:%s\n", + pReceiveMsg->sysHeader.cConsumerSysVersion); + + p->ulMsgTotal++; + const char *pContent = NULL; + unsigned int uiContentLen = 0; + if ((pContent = + rmb_msg_get_content_ptr (pReceiveMsg, &uiContentLen)) != NULL) + { + if (p->uiLog == 1) + { + printf ("***get message len=%d,%s\n", uiContentLen, pContent); + } + //if (p->uiLogServer == 1) { + // rmb_log_for_common(p->pRmbPub->pContext, LOG_MSG_LEVEL_INFO, "test", "%s", pReceiveMsg->sysHeader.cBizSeqNo, pReceiveMsg->sysHeader.cConsumerSeqNo, pReceiveMsg->sysHeader.cOrgSysId, pContent); + //} +// if (pReceiveMsg->iEventOrService == RMB_EVENT_CALL) { + if (strlen (pReceiveMsg->replyTo.cDestName) > 0) + { + char replyContent[MAX_MSG_LEN] = { 0 }; + unsigned int uiReplyLen = 0; + memcpy (replyContent, pContent, uiContentLen); + uiReplyLen += uiContentLen; + memcpy (&replyContent[uiReplyLen], "_reply", strlen ("_reply")); + uiReplyLen += strlen ("_reply"); + replyContent[uiReplyLen] = '\0'; + + rmb_msg_set_content (p->pReplyMsg, replyContent, uiReplyLen); + + char appHeader[10] = "{}"; + rmb_msg_set_app_header (p->pReplyMsg, appHeader, strlen (appHeader)); + //rmb_sub_reply_msg(p->pRmbSub, pReceiveMsg, p->pReplyMsg); + rmb_pub_reply_msg (p->pRmbPub, pReceiveMsg, p->pReplyMsg); + } + rmb_sub_ack_msg (p->pRmbSub, pReceiveMsg); + } + + rmb_msg_free (pReceiveMsg); + + return; +} + +/** + * broad cast sub callback + */ +void func_with_broadcast (const char *buf, const int len, void *pAgv) +//void func_with_broadcast(void *pRecvMsg, void* pAgv) +{ + if (pAgv == NULL) + { + printf ("%s:%d--%s pAgv is null\n", __FILE__, __LINE__, __func__); + return; + } + + StDemoArgv *p = (StDemoArgv *) pAgv; + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + if (pReceiveMsg == NULL) + { + printf ("rmb_msg_malloc failed\n"); + return; + } + + shift_buf_2_msg (pReceiveMsg, buf, len); + + p->ulMsgTotal++; + + const char *pContent = NULL; + unsigned int uiContentLen = 0; + if ((pContent = + rmb_msg_get_content_ptr (pReceiveMsg, &uiContentLen)) != NULL) + { + if (p->uiLog == 1) + { + LOG_PRINT (RMB_LOG_INFO, "receive broadcase content len=%u, %s", + uiContentLen, pContent); + } + } + + rmb_msg_free (pReceiveMsg); +} + +//RR异步时,pub回调函数 +void func_with_rr_rsp (const char *buf, const int len, void *pAgv) +{ + if (pAgv == NULL) + { + printf ("pAgv or pRevMsg is null"); + return; + } + + StDemoArgv *p = (StDemoArgv *) pAgv; + + shift_buf_2_msg (p->pReceiveMsg, buf, len); + + p->ulMsgTotal++; + + const char *pUniqueId = rmb_msg_get_uniqueId_ptr (p->pReceiveMsg); + if (pUniqueId == NULL) + { + printf ("%s:%d-%s ,get uniqueId error!\n", __FILE__, __LINE__, __func__); + } + printf ("receive Msg:uniqueId = %s\n", pUniqueId); + + const char *pContent = NULL; + unsigned int uiContentLen = 0; + + if ((pContent = + rmb_msg_get_content_ptr (p->pReceiveMsg, &uiContentLen)) != NULL) + { + + LOG_PRINT (RMB_LOG_INFO, "recevie reply msg:len=%d,%s\n", uiContentLen, + pContent); + } + + return; +} + +//key is topic, like: dcn-s-serviceid--scense_id AB0-s-11000000-26-0 +int get_dcn_service_scense (const char *key, char *dcn, char *event, + char *consumerSysId, char *service_id, + char *scense_id) +{ + if (key == NULL) + { + printf ("key is null"); + return -1; + } + + char *p = (char *) key; + char *p1 = NULL; + + //判断分隔符数量是否正确 + int i = 0; + + do + { + p1 = strchr (p, '-'); + if (p1 == NULL) + { + break; + } + i++; + p = p1 + 1; + } + while (p != NULL); + + if (i != 4) + { + LOG_PRINT (RMB_LOG_ERROR, "key:%s is error", key); + exit (1); + } + + char temp[100]; + memset (temp, 0x00, sizeof (temp)); + strncpy (temp, key, sizeof (temp) - 1); + + p = strrchr (temp, '-'); + *p = '\0'; + //copy scense id + p = strrchr (temp, '-'); + if (p == NULL || scense_id == NULL) + { + return -1; + } + strcpy (scense_id, p + 1); + *p = '\0'; + + //copy service id + p = strrchr (temp, '-'); + if (p == NULL || service_id == NULL) + { + return -1; + } + strcpy (service_id, p + 1); + *p = '\0'; + + //copy consumerSysId + /* + p = strrchr(temp, '/'); + if (p == NULL) { + return -1; + } + if (consumerSysId != NULL) { + strcpy(consumerSysId, p+1); + } + *p = '\0'; + */ + //copy event + p = strrchr (temp, '-'); + if (p == NULL) + { + return -1; + } + if (event != NULL) + { + strcpy (event, p + 1); + } + *p = '\0'; + + if (dcn == NULL) + { + return -1; + } + strcpy (dcn, temp); + + return 0; +} + +int pub_binary_message (StRmbPub * pRmbPub, const char *cDcn, + const char *cServiceId, const char *cSenaId) +{ + int iRet = 0; + StRmbMsg *pSendMsg = rmb_msg_malloc (); + rmb_msg_clear (pSendMsg); + rmb_msg_set_bizSeqNo (pSendMsg, "12345678901234567890123456789012"); + rmb_msg_set_consumerSeqNo (pSendMsg, "22222678901234567890123456799999"); + rmb_msg_set_orgSysId (pSendMsg, "9999"); + + int iEventOrService = *(cServiceId + 3) - '0'; + int flag = iEventOrService; + printf ("flag: %d\n", flag); + rmb_msg_set_dest (pSendMsg, RMB_DEST_TOPIC, cDcn, iEventOrService, + cServiceId, cSenaId); + + char *p = "This is test binary message"; + char content[1024]; + unsigned int uiConLen = 0; + memset (content, 0x00, sizeof (content)); + content[0] = 0x02; + content[1] = 0; + memcpy (&content[2], p, strlen (p)); + uiConLen = 2 + strlen (p); + + rmb_msg_set_content (pSendMsg, content, uiConLen); + char appHeader[100] = "{}"; + rmb_msg_set_app_header (pSendMsg, appHeader, strlen (appHeader)); + + if (flag == 1) + { + iRet = rmb_pub_send_msg (pRmbPub, pSendMsg); + if (iRet == 0) + { + LOG_PRINT (RMB_LOG_INFO, "send msg=%s OK", pSendMsg->cContent); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_send_msg error!iRet = %d", iRet); + } + rmb_msg_free (pSendMsg); + return 0; + } + else + { + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + iRet = rmb_pub_send_and_receive (pRmbPub, pSendMsg, pReceiveMsg, 5000); + if (iRet == 0) + { + char receiveBuf[1024]; + unsigned int receiveLen = sizeof (receiveBuf); + rmb_msg_get_content (pReceiveMsg, receiveBuf, &receiveLen); + LOG_PRINT (RMB_LOG_INFO, "**********receive reply pkg len=%d", + receiveLen); + int i = 0; + for (i = 0; i < receiveLen; i++) + { + printf ("%c", receiveBuf[i]); + } + printf ("\n***********"); +// printf("%s:%d-%s ,receive reply pkg=%d%s\n", __FILE__, __LINE__, __func__, receiveBuf); + } + else + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_send_and_receive error!iRet = %d", + iRet); + } + rmb_msg_free (pSendMsg); + rmb_msg_free (pReceiveMsg); + return 0; + } + return 0; +} + +void destroy () +{ + if (pRmbSub != NULL) + { + rmb_sub_close_v2 (pRmbSub); + //exit(0); + } + if (pRmbPub != NULL) + { + rmb_pub_close_v2 (pRmbPub); + exit (0); + } +} + +void sigusr2_handle (int iSigVal) +{ + + LOG_PRINT (RMB_LOG_INFO, "sub accept signal USR2"); + //先stop_receive + if (rmb_sub_stop_receive (pRmbSub) != 0) + { + //没有成功停止接收,有异常 + destroy (); + } + else + { + while (rmb_sub_check_req_mq_is_null (pRmbSub) != 0) //本地的共享内存还有未处理完的消息 + { + rmb_sub_do_receive (pRmbSub, 1); + } + //处理完消息之后,退出 + destroy (); + } +} + +int main (int argc, char *argv[]) +{ + if (argc <= 1) + { + printfUsage (argv[0]); + } + + int ret = rmb_load_config ("./rmb.conf"); + if (ret != 0) + { + printf ("load rmb config file failed \n"); + return -1; + } + pRmbSub = (StRmbSub *) calloc (1, sizeof (StRmbSub)); + if (pRmbSub == NULL) + { + printf ("%s:%d -- calloc for pRmbSub failed:%s\n", __func__, __LINE__, + strerror (errno)); + return 0; + } + pRmbPub = (StRmbPub *) calloc (1, sizeof (StRmbPub)); + if (pRmbPub == NULL) + { + printf ("%s:%d -- calloc for pRmbPub failed:%s\n", __func__, __LINE__, + strerror (errno)); + return 0; + } + + char event[10]; + char dcn[10]; + char service_id[10]; + char scenario_id[10]; + + enum EVENT_OR_SERVICE_CALL event_or_serv = RMB_SERVICE_CALL; + + int iRet = 0; + + if (strcmp (argv[1], "sub") == 0) + { + //./process_name sub sleep_time log_control process_nums queue1 queue2 ... + // example: ./rmb_demo sub 1 1 1 FT0-s-98200001-01-1 + if (argc < 6) + printfUsage (argv[0]); + signal (SIGUSR2, sigusr2_handle); + unsigned int uiShmKeyForReq = pRmbStConfig->uiShmKeyForReq; + unsigned int uiShmSizeForReq = pRmbStConfig->uiShmSizeForReq; + char strFifoPathForReq[128]; + memset (strFifoPathForReq, 0x00, sizeof (strFifoPathForReq)); + strcpy (strFifoPathForReq, pRmbStConfig->strFifoPathForReq); + + LOG_PRINT (RMB_LOG_INFO, "sub pid:%d process nums:%d", getpid (), + atoi (argv[4])); + //多进程 + int i; + for (i = 1; i < atoi (argv[4]); i++) + { + if (fork () == 0) + { + uiShmKeyForReq += 4096 * i; + memset (strFifoPathForReq, 0x00, sizeof (strFifoPathForReq)); + snprintf (strFifoPathForReq, sizeof (strFifoPathForReq), + "./tmp_req_%d.fifo", getpid ()); + break; + } + } + + if ((iRet = rmb_sub_init (pRmbSub)) != 0) + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_sub_init error=%d", iRet); + return -1; + } + + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + StRmbMsg *pReplyMsg = rmb_msg_malloc (); + StDemoArgv *pTmp = (StDemoArgv *) calloc (1, sizeof (StDemoArgv)); + if (pReceiveMsg == NULL || pReplyMsg == NULL || pTmp == NULL) + { + LOG_PRINT (RMB_LOG_ERROR, + "pReceiveMsg is NULL or pReplyMsg is NULL or pTmp is NULL"); + return -1; + } + pTmp->pRmbPub = pRmbPub; + pTmp->pRmbSub = pRmbSub; + pTmp->pReplyMsg = pReplyMsg; + pTmp->uiLog = (unsigned int) atoi (argv[3]); + /////////// + pTmp->ulMsgTotal = 0; + pTmp->uiSleepTime = (unsigned int) atoi (argv[2]); + pTmp->uiFlag = 0; + + //注册回调 + if ((iRet = + rmb_sub_add_reveive_req_by_mq_v2 (pRmbSub, strFifoPathForReq, + uiShmKeyForReq, uiShmSizeForReq, + func_with_req, pTmp)) != 0) + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_sub_add_reveive_req_by_mq error=%d", + iRet); + return -1; + } + + st_rmb_queue_info *pQueueInfo; + pQueueInfo = + (st_rmb_queue_info *) malloc (sizeof (st_rmb_queue_info) * 100); + if (pQueueInfo == NULL) + { + printf ("malloc for pQueueInfo failed\n"); + return -1; + } + memset (pQueueInfo, 0x00, (sizeof (st_rmb_queue_info) * 100)); + st_rmb_queue_info *p = pQueueInfo; + unsigned int uiQueneNums = 0; + + for (i = 0; (i < argc - 5) && (i < 100); i++) + { + memset (event, 0x00, sizeof (event)); + memset (dcn, 0x00, sizeof (dcn)); + memset (service_id, 0x00, sizeof (service_id)); + memset (scenario_id, 0x00, sizeof (scenario_id)); + if ((iRet = + get_dcn_service_scense (argv[i + 5], dcn, event, NULL, service_id, + scenario_id)) < 0) + { + printf ("parse queue:%s failed,iRet=%d\n", argv[i + 5], iRet); + continue; + } + if (strcmp (event, "e") == 0) + { + event_or_serv = RMB_EVENT_CALL; + } + else + { + event_or_serv = RMB_SERVICE_CALL; + } + + LOG_PRINT (RMB_LOG_INFO, + "sub:dcn:%s event:%d service_id:%s scenario_id:%s", dcn, + (int) event_or_serv, service_id, scenario_id); + + strncpy (p->cDcn, dcn, strlen (dcn)); + strncpy (p->cServiceId, service_id, strlen (service_id)); + strncpy (p->cScenarioId, scenario_id, strlen (scenario_id)); + p += 1; + uiQueneNums += 1; + } + + if ((iRet = rmb_sub_add_listen (pRmbSub, pQueueInfo, uiQueneNums)) != 0) + { + printf ("rmb_sub_add_listen failed, iRet = %d\n", iRet); + return -2; + } + + unsigned long last_msg_total = 0; + unsigned long print_msg_ctrl = 0; + for (;;) + { + //to do recevive + rmb_sub_do_receive (pRmbSub, 1); + + print_msg_ctrl++; + + if (print_msg_ctrl > 5000) + { + if (last_msg_total != pTmp->ulMsgTotal) + { + printf ("%s:%d -- sub: pid:%d receive message total:%lu\n", + __FILE__, __LINE__, getpid (), pTmp->ulMsgTotal); + print_msg_ctrl = 0; + last_msg_total = pTmp->ulMsgTotal; + } + } + } + } + + else if (strcmp (argv[1], "sub_broadcast") == 0) + { + //./process_name sub_broadcast process_nums log_control topic(queue)1 topic(queue)2 ... + unsigned int uiShmKeyForBroadcastReq = pRmbStConfig->uiShmKeyForBroadcast; + unsigned int uiShmSizeRorBroadcastReq = + pRmbStConfig->uiShmSizeForBroadcast; + char strFifoPathForBroadcastReq[128]; + + snprintf (strFifoPathForBroadcastReq, sizeof (strFifoPathForBroadcastReq), + "%s", pRmbStConfig->strFifoPathForReq); + + printf ("sub_broadcast process nums:%d", atoi (argv[2])); + //mutil-process + int i; + for (i = 1; i < atoi (argv[2]); i++) + { + if (fork () == 0) + { + uiShmKeyForBroadcastReq += 4096 * i; + memset (uiShmSizeRorBroadcastReq, 0x00, + sizeof (uiShmSizeRorBroadcastReq)); + snprintf (strFifoPathForBroadcastReq, + sizeof (strFifoPathForBroadcastReq), "./tmp_req_%d.fifo", + getpid ()); + break; + } + } + + if ((iRet = rmb_sub_init (pRmbSub)) != 0) + { + printf ("rmb_sub_init failed\n"); + return -1; + } + + //StRmbMsg *pReceiveMsg = rmb_msg_malloc(); + StDemoArgv *pTmp = (StDemoArgv *) calloc (1, sizeof (StDemoArgv)); + pTmp->pRmbPub = pRmbPub; + pTmp->pRmbSub = pRmbSub; + pTmp->pReplyMsg = NULL; + pTmp->ulMsgTotal = 0; + pTmp->uiLog = (unsigned int) atoi (argv[3]); + + //rmb_callback_func func, void *func_msg, void* func_argv + if ((iRet = + rmb_sub_add_reveive_broadcast_by_mq_v2 (pRmbSub, + strFifoPathForBroadcastReq, + uiShmKeyForBroadcastReq, + uiShmSizeRorBroadcastReq, + func_with_broadcast, + pTmp)) != 0) + { + LOG_PRINT (RMB_LOG_ERROR, + "rmb_sub_add_reveive_broadcast_by_mq_v2 failed!iRet=%d", + iRet); + return -1; + } + + st_rmb_queue_info *pQueueInfo; + pQueueInfo = + (st_rmb_queue_info *) malloc (sizeof (st_rmb_queue_info) * 100); + if (pQueueInfo == NULL) + { + printf ("malloc for pQueueInfo failed\n"); + return -1; + } + memset (pQueueInfo, 0x00, (sizeof (st_rmb_queue_info) * 100)); + st_rmb_queue_info *p = pQueueInfo; + unsigned int uiQueneNums = 0; + + for (i = 0; (i < argc - 4) && (i < 100); i++) + { + memset (dcn, 0x00, sizeof (dcn)); + memset (service_id, 0x00, sizeof (service_id)); + memset (scenario_id, 0x00, sizeof (scenario_id)); + + if (get_dcn_service_scense + (argv[i + 4], dcn, NULL, NULL, service_id, scenario_id) < 0) + { + printf ("parse:%s failed\n", argv[i + 4]); + continue; + } + LOG_PRINT (RMB_LOG_INFO, "board_sub: dcn:%s service_id:%s scense_id:%s", + dcn, service_id, scenario_id); + + event_or_serv = RMB_EVENT_CALL; + + strncpy (p->cDcn, dcn, strlen (dcn)); + strncpy (p->cServiceId, service_id, strlen (service_id)); + strncpy (p->cScenarioId, scenario_id, strlen (scenario_id)); + p += 1; + uiQueneNums += 1; + } + + if ((iRet = rmb_sub_add_listen (pRmbSub, pQueueInfo, uiQueneNums)) != 0) + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_sub_add_listen failed, iRet = %d", iRet); + return -2; + } + + unsigned long print_msg_ctrl = 0; + for (;;) + { + rmb_sub_do_receive (pRmbSub, 1); + print_msg_ctrl++; + + if (print_msg_ctrl > 3000) + { + LOG_PRINT (RMB_LOG_INFO, "sub: pid:%d receive message total:%lu", + getpid (), pTmp->ulMsgTotal); + print_msg_ctrl = 0; + } + } + + } + else if (strcmp (argv[1], "pub") == 0) + { + //./process_name pub pthread_nums log_control msg_nums msg_len ttl_time sleep_time queue1 queue2 ... + /* + * pub:指"rr_sync_pub" or "unicast_pub" + * pthread_nums: 发送消息的线程数量 + * log_control: 是否打印收发消息的长度,这个是针对包大小测试加的 + * msg_nums: 每个线程发送消息的数量或单线程往每个queue上发送的消息数量 + * msg_len: 发送的消息体的总的长度,这个主要是针对测试包大小而加入的 + * queue1、queue2...: 发送消息使用的queue + * + * example: ./rmb_demo pub 1 1 1 10 3000 1 FT0-s-98200001-01-1 + */ + if (argc < 9) + printfUsage (argv[0]); + + if ((iRet = rmb_pub_init (pRmbPub)) != 0) + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_init error=%d", iRet); + return -1; + } + + int sleep_time = 0; + if (atoi (argv[7]) > 0) + sleep_time = atoi (argv[7]); + char *msg = (char *) calloc (sizeof (char), atoi (argv[5]) + 1); + int msg_len = strlen (send_msg); + int copy_nums = atoi (argv[5]) / msg_len; + + char *p = msg; + int i; + for (i = 0; i < copy_nums; i++) + { + memcpy (p, send_msg, msg_len); + p += msg_len; + } + + if (atoi (argv[5]) % msg_len != 0) + { + memcpy (p, send_msg, atoi (argv[5]) % msg_len); + } + + if (strcmp (argv[3], "1") == 0) + { + LOG_PRINT (RMB_LOG_INFO, "pub send msg len:%d, content len:%lu", + atoi (argv[5]), strlen (msg)); + } + + tMessage msg_info; + msg_info.type = 0; + msg_info.pid = getpid (); + msg_info.process_num = 1; + msg_info.send_msg_num = 0; + msg_info.recv_msg_num = 0; + enum EVENT_OR_SERVICE_CALL event_or_serv = RMB_SERVICE_CALL; + //queue numbers + int iQueueNumbers = argc - 8; + if (atoi (argv[2]) == 1) + { //single thread + for (i = 0; i < iQueueNumbers; i++) + { + char event[100]; + char dcn[100]; + char service_id[100]; + char scenario_id[100]; + + memset (event, 0x00, sizeof (event)); + memset (dcn, 0x00, sizeof (dcn)); + memset (service_id, 0x00, sizeof (service_id)); + memset (scenario_id, 0x00, sizeof (scenario_id)); + + if (get_dcn_service_scense + (argv[i + 8], dcn, event, NULL, service_id, scenario_id) < 0) + { + continue; + } + + if (strcmp (event, "e") == 0) + { + event_or_serv = RMB_EVENT_CALL; + } + + LOG_PRINT (RMB_LOG_INFO, + "dcn:%s event:%d service_id:%s scenario_id:%s", dcn, + (int) event_or_serv, service_id, scenario_id); + + unsigned long pub_send_msg = 0; + int l; + for (l = 0; l < atoi (argv[4]); l++) + { + iRet = + pubOwnMessage (pRmbPub, event_or_serv, atol (argv[6]), dcn, + service_id, scenario_id, + (unsigned int) atoi (argv[3]), msg); + if (iRet == 0) + { + pub_send_msg++; + } + if (sleep_time > 0) + sleep (sleep_time); + } + + msg_info.send_msg_num += (unsigned int) atoi (argv[4]); + msg_info.recv_msg_num += pub_send_msg; + + if (event_or_serv == RMB_EVENT_CALL) + { + LOG_PRINT (RMB_LOG_INFO, + "pid:%ld queue:%s pub send:%d and success:%lu\n", + (long) getpid (), argv[i + 8], atoi (argv[4]), + pub_send_msg); + } + else + { + LOG_PRINT (RMB_LOG_INFO, + "pid:%ld queue:%s pub send:%d and recv:%lu\n", + (long) getpid (), argv[i + 8], atoi (argv[4]), + pub_send_msg); + } + } + rmb_pub_close (pRmbPub); + } + else if (atoi (argv[2]) > 1) + { //mutil thread + //./process_name pub pthread_nums log_control msg_nums msg_len msg ttl_time queue1 queue2 ... + pthread_t thVec[200]; + tThreadArgs tArgs[200]; + unsigned int thread_nums = + (atoi (argv[2]) < 200 ? atoi (argv[2]) : 200); + for (i = 0; i < iQueueNumbers && i < 200; ++i) + { + tArgs[i].pRmbPub = pRmbPub; + tArgs[i].times = atoi (argv[4]); + tArgs[i].iContent = i; + tArgs[i].ulMsgSucc = 0; + tArgs[i].ttl = atol (argv[6]); + tArgs[i].pMsg = msg; + + char event[100]; + + memset (event, 0x00, sizeof (event)); + memset (tArgs[i].cDcn, 0x00, sizeof (tArgs[i].cDcn)); + memset (tArgs[i].cServiceId, 0x00, sizeof (tArgs[i].cServiceId)); + memset (tArgs[i].cSenaId, 0x00, sizeof (tArgs[i].cSenaId)); + + get_dcn_service_scense (argv[i + 8], tArgs[i].cDcn, event, NULL, + tArgs[i].cServiceId, tArgs[i].cSenaId); + + if (strcmp (event, "e") == 0) + { + event_or_serv = RMB_EVENT_CALL; + } + tArgs[i].event_or_service = event_or_serv; + } + if (thread_nums > iQueueNumbers) + { + for (i = iQueueNumbers; i < thread_nums; i++) + { + tArgs[i].pRmbPub = pRmbPub; + tArgs[i].times = atoi (argv[4]); + tArgs[i].event_or_service = + tArgs[i % iQueueNumbers].event_or_service; + tArgs[i].iContent = i; + tArgs[i].pMsg = msg; + + memset (tArgs[i].cDcn, 0x00, sizeof (tArgs[i].cDcn)); + strcpy (tArgs[i].cDcn, tArgs[i % iQueueNumbers].cDcn); + + memset (tArgs[i].cServiceId, 0x00, sizeof (tArgs[i].cServiceId)); + strcpy (tArgs[i].cServiceId, tArgs[i % iQueueNumbers].cServiceId); + + memset (tArgs[i].cSenaId, 0x00, sizeof (tArgs[i].cSenaId)); + strcpy (tArgs[i].cSenaId, tArgs[i % iQueueNumbers].cSenaId); + } + } + for (i = 0; i < thread_nums; ++i) + { + if ((iRet = + pthread_create (&thVec[i], NULL, (void *) &mutil_thread_for_pub, + (void *) &tArgs[i])) != 0) + { + printf ("%d thread error!iRet=%d\n", i, iRet); + } + } + + unsigned long total_msg = 0; + for (i = 0; i < thread_nums; ++i) + { + if ((iRet = pthread_join (thVec[i], NULL)) != 0) + { + printf ("%d thread error!iRet=%d\n", i, iRet); + } + else + { + total_msg += tArgs[i].ulMsgSucc; + } + } + if (event_or_serv == RMB_SERVICE_CALL) + { + LOG_PRINT (RMB_LOG_INFO, "*****pub send msg:%d recv:%lu", + thread_nums * atoi (argv[4]), total_msg); + } + else + { + LOG_PRINT (RMB_LOG_INFO, "*****pub send msg:%d success:%lu", + thread_nums * atoi (argv[4]), total_msg); + } + + msg_info.send_msg_num = thread_nums * atoi (argv[4]); + msg_info.recv_msg_num = total_msg; + } + + free (msg); + } + else if (strcmp (argv[1], "rr_async_pub") == 0) + { + //./test_rmb_capi rr_async_pub process_nums log_control msg_nums msg_len sleep_time timeout queue + if (argc < 9) + printfUsage (argv[0]); + + unsigned int uiShmKeyForRsq = pRmbStConfig->uiShmKeyForRRrsp; + unsigned int uiShmSizeForRsq = pRmbStConfig->uiShmSizeForRRrsp; + char strFifoPathForRsq[128]; + memset (strFifoPathForRsq, 0x00, sizeof (strFifoPathForRsq)); + strcpy (strFifoPathForRsq, pRmbStConfig->strFifoPathForRRrsp); + + LOG_PRINT (RMB_LOG_INFO, + "***RR async, process total:%d, per process send message numbers:%d", + atoi (argv[2]), atoi (argv[4])); + + int sleep_time = 0; + if (atoi (argv[6]) > 0) + sleep_time = atoi (argv[6]); + int i; + for (i = 1; i < atoi (argv[2]); i++) + { + if (fork () == 0) + { + uiShmKeyForRsq += 4096 * i; + memset (strFifoPathForRsq, 0x00, sizeof (strFifoPathForRsq)); + snprintf (strFifoPathForRsq, sizeof (strFifoPathForRsq), + "./tmp_rsq_%d.fifo", getpid ()); + break; + } + } + + if ((iRet = rmb_pub_init (pRmbPub)) != 0) + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_init error=%d", iRet); + return -1; + } + + if ((iRet = rmb_sub_init (pRmbSub)) != 0) + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_sub_init error=%d", iRet); + return -1; + } + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + StRmbMsg *pReplyMsg = rmb_msg_malloc (); + StDemoArgv *pTmp = (StDemoArgv *) calloc (1, sizeof (StDemoArgv)); + pTmp->pRmbPub = pRmbPub; + pTmp->pRmbSub = pRmbSub; + pTmp->pReceiveMsg = pReceiveMsg; + pTmp->pReplyMsg = pReplyMsg; + pTmp->uiLog = (unsigned int) atoi (argv[3]); + pTmp->ulMsgTotal = 0; + + if ((iRet = + rmb_sub_add_reveive_rsp_by_mq_v2 (pRmbSub, strFifoPathForRsq, + uiShmKeyForRsq, uiShmSizeForRsq, + func_with_rr_rsp, pTmp)) != 0) + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_sub_add_reveive_req_by_mq error=%d", + iRet); + return -1; + } + + //./test_rmb_capi rr_async_pub process_nums log_control msg_nums msg_len msg queue + char *msg = (char *) calloc (sizeof (char), atoi (argv[5]) + 1); + int msg_len = strlen (send_msg); + int copy_nums = atoi (argv[5]) / msg_len; + + char *p = msg; + for (i = 0; i < copy_nums; i++) + { + memcpy (p, send_msg, msg_len); + p += msg_len; + } + + if (atoi (argv[5]) % msg_len != 0) + { + memcpy (p, send_msg, atoi (argv[5]) % msg_len); + } + + LOG_PRINT (RMB_LOG_INFO, "rr async pub send msg len:%d, content len:%lu", + atoi (argv[5]), strlen (msg)); + + StRmbMsg *pSendMsg = rmb_msg_malloc (); + + static unsigned int uiSeq = 1; + struct timeval tv; + gettimeofday (&tv, NULL); + unsigned long ulNowTime = tv.tv_sec * 1000 + tv.tv_usec / 1000; + char cSeqNo[33]; + snprintf (cSeqNo, sizeof (cSeqNo), "%013lu%019u", ulNowTime, uiSeq++); + rmb_msg_set_bizSeqNo (pSendMsg, cSeqNo); + rmb_msg_set_consumerSeqNo (pSendMsg, cSeqNo); + rmb_msg_set_orgSysId (pSendMsg, "9999"); + rmb_msg_set_content (pSendMsg, msg, strlen (msg)); + char appHeader[100] = "{}"; + rmb_msg_set_app_header (pSendMsg, appHeader, strlen (appHeader)); + + //增加多个队列支持 + unsigned int send_msg = 0; + for (i = 0; i < argc - 7; i++) + { + char dcn[100]; + char service_id[100]; + char scense_id[100]; + memset (dcn, 0x00, sizeof (dcn)); + memset (service_id, 0x00, sizeof (service_id)); + memset (scense_id, 0x00, sizeof (scense_id)); + if (get_dcn_service_scense + (argv[i + 8], dcn, NULL, NULL, service_id, scense_id) < 0) + { + printf ("RR async pub queue error:%s\n", argv[i + 6]); + continue; + } + printf ("dcn:%s service_id:%s scense_id:%s\n", dcn, service_id, + scense_id); + + rmb_msg_set_dest (pSendMsg, RMB_DEST_TOPIC, dcn, RMB_SERVICE_CALL, + service_id, scense_id); + int j; + for (j = 0; j < atoi (argv[4]); j++) + { + iRet = rmb_pub_send_rr_msg_async (pRmbPub, pSendMsg, atoi (argv[7])); + if (iRet != 0) + { + printf ("%s:%d-%s ,rmb_pub_send_and_receive error!iRet = %d\n", + __FILE__, __LINE__, __func__, iRet); + } + else + { + send_msg++; + if (sleep_time > 0) + sleep (sleep_time); + } + } + } + + LOG_PRINT (RMB_LOG_INFO, "pid:%d rmb_pub_async_message success total: %u", + (int) getpid (), send_msg); + + tMessage msg_info; + msg_info.type = 0; + msg_info.pid = getpid (); + msg_info.process_num = atoi (argv[4]); + msg_info.send_msg_num = atoi (argv[4]) * (argc - 7); + msg_info.recv_msg_num = 0; + + unsigned long last_msg_total = 0; + unsigned long print_msg_ctrl = 0; + for (;;) + { + //to do recevive + rmb_sub_do_receive (pRmbSub, 1); + print_msg_ctrl++; + + if (print_msg_ctrl > 10000) + { + print_msg_ctrl = 0; + if (pTmp->ulMsgTotal != last_msg_total) + { + LOG_PRINT (RMB_LOG_INFO, "pid:%d get_reply_msg_total:%lu", + (int) getpid (), pTmp->ulMsgTotal); + last_msg_total = pTmp->ulMsgTotal; + } + } + } + } + else if (strcmp (argv[1], "pub_board") == 0) + { + //./process_name pub_board message_nums message orgId queue + //send board message + if ((iRet = rmb_pub_init (pRmbPub)) != 0) + { + LOG_PRINT (RMB_LOG_ERROR, "rmb_pub_init error=%d", iRet); + return -1; + } + + enum EVENT_OR_SERVICE_CALL event_or_serv = RMB_SERVICE_CALL; + + char event[100]; + char dcn[100]; + char service_id[100]; + char scenario_id[100]; + + memset (event, 0x00, sizeof (event)); + memset (dcn, 0x00, sizeof (dcn)); + memset (service_id, 0x00, sizeof (service_id)); + memset (scenario_id, 0x00, sizeof (scenario_id)); + + iRet = + get_dcn_service_scense (argv[5], dcn, event, NULL, service_id, + scenario_id); + + if (iRet < 0) + { + printf ("get_dcn_service_scense return:%d\n", iRet); + return iRet; + } + + if (strcmp (event, "e") == 0) + { + event_or_serv = RMB_EVENT_CALL; + } + LOG_PRINT (RMB_LOG_INFO, "dcn:%s event:%d service_id:%s scenario_id:%s", + dcn, (int) event_or_serv, service_id, scenario_id); + unsigned long pub_send_msg = 0; + int i; + for (i = 0; i < atoi (argv[2]); i++) + { + iRet = + pub_board_message (pRmbPub, event_or_serv, 0, dcn, service_id, + scenario_id, argv[4], 1, argv[3]); + if (iRet == 0) + { + pub_send_msg++; + } + } + } + + else + { + printf ("unknown argv[1]:%s\n", argv[1]); + printfUsage (argv[0]); + } + + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/message_log_api.h b/eventmesh-sdks/eventmesh-sdk-c/include/message_log_api.h new file mode 100644 index 0000000000..8c2eb9516d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/message_log_api.h @@ -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. + +#ifndef __MESSAGE_LOG_API_H_ +#define __MESSAGE_LOG_API_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rmb_define.h" +#include "rmb_pub.h" + +#define LOG_MSG_COM_CONSUMERID "consumerId" +#define LOG_MSG_COM_LOGNAME "logName" +#define LOG_MSG_COM_TIMESTAMP "logTimestamp" +#define LOG_MSG_COM_CONTENT "content" +#define LOG_MSG_COM_LOGTYPE "logType" +#define LOG_MSG_COM_LANG "lang" +#define LOG_MSG_COM_ID "id" +#define LOG_MSG_COM_PROCESSID "processId" +#define LOG_MSG_COM_THREADID "threadId" +#define LOG_MSG_COM_CONSUMERSVRID "consumerSvrId" +#define LOG_MSG_COM_LEVEL "level" +#define LOG_MSG_COM_EXTFIELDS "extFields" + +#define LOG_INFO_LEVEL "info" +#define LOG_DEBUG_LEVEL "debug" +#define LOG_WARN_LEVEL "warn" +#define LOG_ERROR_LEVEL "error" +#define LOG_FATAL_LEVEL "fatal" + +//应用可以调用此接口上传log日志 + int rmb_log_for_common (StContext * pStContext, const char *iLogLevel, + const char *cLogName, const char *content, + const char *extFields); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_access_config.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_access_config.h new file mode 100644 index 0000000000..3df3ded354 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_access_config.h @@ -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. + +#ifndef RMB_ACCESS_CONFIG_H_ +#define RMB_ACCESS_CONFIG_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + + int rmb_get_wemq_proxy_list_num (); + + int rmb_get_wemq_proxy_list_used (); + +//int wemq_proxy_load_servers(char* url, long timeout, const char* path); + int wemq_proxy_load_servers (const char *url, long timeout); + + int wemq_proxy_get_server (char *host, size_t size, unsigned int *port); + + void wemq_proxy_goodbye (const char *host, unsigned int port); + + void wemq_proxy_to_black_list (const char *host, unsigned int port); + + int wemq_proxy_ip_is_connected (); + + void split_str (char *ips, char ipArray[][50], int *len); + +#ifdef __cplusplus +} +#endif + +#endif /* RMB_ACCESS_CONFIG_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_cfg.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_cfg.h new file mode 100644 index 0000000000..3ce38bd837 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_cfg.h @@ -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. + +#ifndef RMB_CFG_H_ +#define RMB_CFG_H_ + +#include "rmb_define.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define CFG_STRING (int)1 +#define CFG_INT (int)2 +#define CFG_LONG (int)3 +#define CFG_DOUBLE (int)4 +#define CFG_LINE (int)5 +#define CFG_SHORT (int)6 + +#define US 0x1f + +#define MAX_CONFIG_LINE_LEN 1023 + + void RMB_TLib_Cfg_GetConfig (char *sConfigFilePath, ...); + +#define Rmb_TLib_Cfg_GetConfig(sConfigFilePath,fmt,args...) RMB_TLib_Cfg_GetConfig(sConfigFilePath,fmt,## args) + +/** + * Function: rmb_load_config + * Description: rmb load configure + * Return: + * 0: success + * -1: failed + */ + int rmb_load_config (const char *configPath); + + const char *rmb_get_host_ip (); + + void rmb_get_config_python (RmbPythonConfig * config); + + const char *getRmbLastError (); + +#ifdef __cplusplus +} +#endif + +#endif /* RMB_CFG_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_common.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_common.h new file mode 100644 index 0000000000..8bdf7745ba --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_common.h @@ -0,0 +1,269 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _RMB_COMMON_H_ +#define _RMB_COMMON_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include +#include + + extern unsigned int g_uiSendMsgSeq; + extern unsigned int g_uiRecvMsgSeq; +//extern unsigned int g_iSendReq = 0; +#define MAX_SEND_MSG_SEQ 65535 + extern unsigned int DEFAULT_WINDOW_SIZE; +#define CURRENT_WINDOW_SIZE (((g_uiRecvMsgSeq) <= (g_uiSendMsgSeq)) ? ((g_uiSendMsgSeq) - (g_uiRecvMsgSeq)) : (MAX_SEND_MSG_SEQ - (g_uiRecvMsgSeq) + (g_uiSendMsgSeq))) + + static int cmpQueueStr (const void *a, const void *b) + { + return strcmp (((StQueueName *) a)->cQueueName, + ((StQueueName *) b)->cQueueName); + } + + static int cmpQueueNodeStr (const void *a, const void *b) + { + return strcmp (((StQueueNode *) a)->cQueueName, + ((StQueueNode *) b)->cQueueName); + } + + static int cmpServiceStatusStr (const void *a, const void *b) + { +// if (((StServiceStatus*)a)->ulGetTimes == 0) +// { +// return 1; +// } +// if (((StServiceStatus*)b)->ulGetTimes == 0) +// { +// return -1; +// } +// if (((StServiceStatus*)a)->ulGetTimes < ((StServiceStatus*)b)->ulGetTimes) +// { +// return 1; +// } + int iRet = + strcmp (((StServiceStatus *) a)->strServiceId, + ((StServiceStatus *) b)->strServiceId); + if (iRet != 0) + { + return iRet; + } + iRet = + strcmp (((StServiceStatus *) a)->strScenarioId, + ((StServiceStatus *) b)->strScenarioId); + if (iRet != 0) + { + return iRet; + } + iRet = + strcmp (((StServiceStatus *) a)->strTargetOrgId, + ((StServiceStatus *) b)->strTargetOrgId); + if (iRet != 0) + { + return iRet; + } + if (((StServiceStatus *) a)->cFlagForOrgId < + ((StServiceStatus *) a)->cFlagForOrgId) + { + return -1; + } + else if (((StServiceStatus *) a)->cFlagForOrgId > + ((StServiceStatus *) a)->cFlagForOrgId) + { + return 1; + } + return 0; + } + + static int cmpBroadNodeStr (const void *a, const void *b) + { + int iRet = + strcmp (((StBroadcastNode *) a)->strServiceId, + ((StBroadcastNode *) b)->strServiceId); + if (iRet != 0) + return iRet; + + iRet = + strcmp (((StBroadcastNode *) a)->strScenarioId, + ((StBroadcastNode *) b)->strScenarioId); + if (iRet != 0) + return iRet; + +// iRet = strcmp(((StBroadcastNode*)a)->cConsumerSysId, ((StBroadcastNode*)b)->cConsumerSysId); +// if (iRet != 0) +// return iRet; + + return 0; + } + +/* +typedef struct StQueueTree +{ + char queueName[30]; + struct StQueueTree *pLeft; + struct StQueueTree *pRight; +}StQueueTree; + +static StQueueTree* InsertQueue(StQueueTree* pRoot, const char *cQueuName) +{ + StQueueTree* pCurNode = pRoot; + StQueueTree* pTmp; + StQueueTree* pNewNode = (StQueueTree*)malloc(sizeof(StQueueTree)); + strncpy(pNewNode->queueName, cQueuName, sizeof(pNewNode->queueName)); + pNewNode->pLeft = NULL; + pNewNode->pRight = NULL; + + if(pCurNode == NULL) + { + return pNewNode; + } + else + { + while(pCurNode != NULL) + { + pTmp = pCurNode; + if( strcmp(cQueuName, pTmp->queueName) > 0) + { + pCurNode = pCurNode->pRight; + } + else + { + pCurNode = pCurNode->pLeft; + } + } + + if(strcmp(cQueuName, pTmp->queueName) > 0) + { + pTmp->pRight = pNewNode; + } + else + { + pTmp->pLeft = pNewNode; + } + } + return pRoot; +} + +static StQueueTree* FindQueue(StQueueTree* pRoot, const char *cQueuName) +{ + int iRet = 1; + StQueueTree *pCurNode = pRoot; + while (iRet != 0) + { + if (pCurNode == NULL) + { + return NULL; + } + iRet = strcmp(cQueuName, pCurNode->queueName); + if( iRet > 0) + { + pCurNode = pCurNode->pRight; + } + else if( iRet < 0) + { + pCurNode = pCurNode->pLeft; + } + else + { + return pCurNode; + } + } + return NULL; +} + +typedef struct StQueueName StQueueName; + +static int rmb_partition(StQueueName* pQueueList,int low,int high) +{ + StQueueName tmpQueueName; + strcpy(tmpQueueName.cQueueName, (pQueueList + low)->cQueueName); + while(low < high) + { + if(lowcQueueName, tmpQueueName.cQueueName) >= 0) + { + --high; + } + strcpy((pQueueList+low)->cQueueName, (pQueueList+high)->cQueueName); + + if(lowcQueueName, tmpQueueName.cQueueName) <= 0) + { + ++low; + } + strcpy((pQueueList+high)->cQueueName, (pQueueList+low)->cQueueName); + } + strcpy((pQueueList + low)->cQueueName, tmpQueueName.cQueueName); + return low; +} + +static void rmb_quick_sort(StQueueName* pQueueList,int low,int high) +{ + if(lowcQueueName, cQueueName); + if ( iRet == 0) + { + return (pQueueList + m); + } + else if (iRet < 0) + { + if (i == m) + { + return NULL; + } + i = m; + } + else if (iRet > 0) + { + if (j == m) + { + return NULL; + } + j = m; + } + } + return NULL; +} +*/ +#ifdef __cplusplus +} +#endif + +#endif /* _RMB_COMMON_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_context.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_context.h new file mode 100644 index 0000000000..e4677db3fd --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_context.h @@ -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. + +#ifndef RMB_CONTEXT_H_ +#define RMB_CONTEXT_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rmb_define.h" + + int rmb_context_init (StContext * pStContext); + + int rmb_context_add_rsp_socket (StContext * pStContext, + const char *cLocalIp, + unsigned short usReplyPort); + + int rmb_context_add_req_socket (StContext * pStContext, + const char *cLocalIp, + unsigned short usReqPort); + + int rmb_context_add_broadcast_socket (StContext * pStContext, + const char *cLocalIp, + unsigned short usBroadcastPort); + + int rmb_context_add_req_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv); + int rmb_context_add_rr_rsp_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + int rmb_context_add_broadcast_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + + int rmb_context_enqueue (StContext * pStContext, + const enum RmbMqIndex uiMsgType, const char *data, + unsigned int uiDataLen); + +#ifdef __cplusplus +} +#endif + +#endif /* RMB_CONTEXT_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_define.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_define.h new file mode 100644 index 0000000000..20f8ea6f13 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_define.h @@ -0,0 +1,1264 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RMB_DEFINE_H_ +#define RMB_DEFINE_H_ +#ifdef __cplusplus +extern "C" +{ +#endif + +/* +rmb_define.h +RMB基本定义 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include "rmb_mq.h" +#include "rmb_log.h" +#include "rmb_errno.h" +#include "wemq_fifo.h" + +#include "wemq_topic_list.h" +#include "wemq_proto.h" + +#include +#include +#include +#include +#include + +#define RMBVERSION "2.2.0" +#define RMBVERSIONFORBIZ "00002200" + static const char rmbVersion[20] = "2.2.0"; + +#define DEFAULT_MSG_MAX_LIVE_TIME 14400000 +#define RR_ASYNC_MSG_MAX_LIVE_TIME 60000 +#define DEFAULT_DCN_LENGTH 3 +#define DEFAULT_SERVICE_ID_LENGTH 8 +#define DEFAULT_SCENE_ID_LENGTH 2 + +#define MAX_FLOWS_IN_A_SESSION 200 //the max flow numbers in one session +#define MAX_QUEUE_SESSIONS_IN_A_CONTEXT 1 //the max session numbers in one context +//#define MAX_LENTH_IN_A_MSG 2150000 //packages buf for send and receive +#define MAX_LENTH_IN_A_MSG 2625825 //packages buf for send and receive +#define MAX_PROPERTY_NUMS 50 //the max numbers for property +#define MAX_PROPERTY_LENTH 255 //the max length for one property +#define MAX_RMB_CONTEXT 2 //the max numbers of context -- solace threads + +#define MAX_SYSHEADER_LENGTH 20 +//流控比中每个topic最大的计数 +#define MAX_TOPIC_COUNT 1000000 +//#define MAX_APPHEADER_LENGTH 50000 +//0.9.12 保持和java一致 +//0.9.16,由于c会加\0,所以字节数需要加1 +//#define MAX_APPHEADER_LENGTH 525000 +//#define MAX_APPHEADER_LENGTH 525001 +#define MAX_APPHEADER_LENGTH (1 << 19) +#define MAX_PROPERTY_SIZE 50 +#define MAX_RET_MSG_SIZE 512 +//0.9.16,由于c会加\0,所以字节数需要加1 +//#define MAX_MSG_CONTENT_SIZE 2100000 +//#define MAX_MSG_CONTENT_SIZE 2100001 +#define MAX_MSG_CONTENT_SIZE (1 << 21) +#define MAX_MSG_ATTACHMENT_SIZE 2048 + +#define MAX_COMMON_SIZE 20 + +#define MAX_LOG_BUF_SIZE 20000 + +#define MAX_SERVICE_STATUS_CACHE_NUMS 1000 +#define MAX_GSL_REQ_BUF_SIZE 100 +#define MAX_GSL_RSP_BUF_SIZE 100 + +#define MAX_GSL_RSP_TOPIC_GROUP_SIZE 256 + +#define GSL_DEFAULT_DCN "GSL" +#define GSL_DEFAULT_SERVICE_ID "12300009" +#define GSL_DEFAULT_SCENE_ID "01" +#define GSL_DEFAULT_COMMON_ORGID "10006" + +#define MAX_RMB_WORKER_NUMS 400 +#define MAX_RMB_PROXY_NUMS 10 + +//for config center +#define WEMQ_ACCESS_SERVER "dynamicKey/v1/wemqAccessServer.json" +#define DYNAMIC_KEY_NAME "dynamicKey/v1" + +#define RMB_REQ_SINGLE "querySingle" +#define RMB_WHITE_LIST_RCV "whitelist-rcv" +#define RMB_WHITE_LIST_SND "whitelist-snd" +#define WEMQ_PROXY_SERVERS "wemq.proxy.servers" + +//#define RMB_WHITE_LIST_RCV_MAX 200 +//#define RMB_WHITE_LIST_SND_MAX 200 +#define RMB_TOPIC_PER_SYS_MAX 10000 +#define MAX_LISTEN_TOPIC_NUM 1000 + +#define RMB_MAX_NORMAL_SESSIONS_IN_A_CONTEXT_FOR_WEMQ 100 //the max normal session in context only for wemq proxy mode + +#define TCP_BUF_SIZE (3<<20) + + enum RmbGslSubcmd + { + GSL_SUBCMD_QUERY_SERVICE = 0x1, + GSL_SUBCMD_NEW_QUERY_SERVICE = 0x11, + GSL_SUBCMD_QUERY_TOPICGROUP = 0x02, + }; + + enum RmbMsgSource + { + RMB_MSG_FROM_SOLACE = 1, + RMB_MSG_FROM_WEMQ = 2, + }; + + enum RmbTargetOrgIdCommitType + { + RMB_COMMIT_BY_OWN = 0, + RMB_COMMIT_BY_API = 1, + }; + + enum RmbFlagForMsgInit + { + RMBMSG_DEST_HAS_SET = 0, + + }; + + enum EVENT_OR_SERVICE_CALL + { + RMB_EVENT_CALL = 0, + RMB_SERVICE_CALL = 1, + }; + + enum RMB_SVR_MODE + { + RMB_OLD_MODE = 0, + RMB_PROXY_WORKER = 1, + }; + + enum RMB_PROXY_MQ_TYPE + { + RMB_PROXY_MQ_RECEIVE = 1, + RMB_PROXY_MQ_SEND = 2, + RMB_PROXY_MQ_RR = 3, + }; + + enum RMB_LOG_POINT + { + RMB_LOG_START_CALL = 0, + RMB_LOG_ENTRY = 1, + RMB_LOG_EXIT = 2, + RMB_LOG_END_CALL = 3, + RMB_LOG_ON_ERROR = 4, + RMB_LOG_OTHER = 5, + }; + + //proxy-worker模式下使用 + typedef struct StMqFifoArg + { + char *_fiFoPath; + unsigned int _shmKey; + unsigned int _shmSize; + } StMqFifoArg; + + enum RMB_MSG_MODE + { + RMB_MSG_SOLACE = 0, + RMB_MSG_WEMQ = 1, + }; + + enum RMB_RSP_CODE + { + RMB_CODE_TIME_OUT = -1, + RMB_CODE_SUSS, + RMB_CODE_OTHER_FAIL, + RMB_CODE_AUT_FAIL, + RMB_CODE_DYED_MSG, + }; + +//**************************for wemq define******************************** +#define MAX_WEMQ_KFIFO_LENGTH (1UL << 16) +#define GETMSGID(buf,msgId) ({\ + char *p = (buf);\ + p += 2 * sizeof(int);\ + p += 3 * sizeof(char);\ + p += sizeof(StSystemHeader);\ + p += 2 * sizeof(StDestination);\ + (msgId) = *((unsigned long*)(p));\ +}) + +#define IS_DYED_MSG "IS_DYED_MSG" +#define MSG_HEAD_COMMAND_STR "command" +#define MSG_HEAD_SEQ_INT "seq" +#define MSG_HEAD_CODE_INT "code" +#define MSG_HEAD_MSG_STR "msg" + +#define MSG_HEAD_TYPE_INT "type" +#define MSG_HEAD_STATUS_INT "status" +#define MSG_HEAD_MSG_STR "msg" +#define MSG_HEAD_TIME_LINT "time" +#define MSG_HEAD_TIMESTAMP_LINT "timestamp" +#define MSG_HEAD_DEST_JSON "dest" +#define MSG_HEAD_DEST_SCENARIO_STR "scenario" +#define MSG_HEAD_DEST_SERVICE_STR "service" +#define MSG_HEAD_DEST_DCN_STR "dcn" +#define MSG_HEAD_DEST_ORGANIZATION_STR "organization" +#define MSG_HEAD_REDIRECT_OBJ "redirect" + +#define MSG_HEAD_SUB_BYPASS_TOPIC "topic" + +#define MSG_HEAD_IDC "idc" +#define MSG_HEAD_IP "ip" + +#define MSG_BODY_TOPIC_LIST_JSON "topicList" +#define MSG_BODY_TOPIC_STR "topic" +#define MSG_BODY_PROPERTY_JSON "properties" +#define MSG_BODY_PROPERTY_MSG_TYPE_STR "msgType" +#define MSG_BODY_PROPERTY_TTL_INT "TTL" +#define MSG_BODY_PROPERTY_SEQ_STR "SEQ" +#define MSG_BODY_PROPERTY_RR_REQUEST_UNIQ_ID_STR "RR_REQUEST_UNIQ_ID" +#define MSG_BODY_PROPERTY_KEYS_STR "keys" +#define MSG_BODY_PROPERTY_REPLYTO_STR "REPLY_TO" +#define MSG_BODY_PROPERTY_BORN_TIME_STR "BORN_TIME" +#define MSG_BODY_PROPERTY_STORE_TIME_STR "STORE_TIME" +#define MSG_BODY_PROPERTY_LEAVE_TIME_STR "LEAVE_TIME" +#define MSG_BODY_PROPERTY_ARRIVE_TIME_STR "ARRIVE_TIME" + +#define MSG_BODY_BYTE_BODY_JSON "body" +#define MSG_BODY_BYTE_BODY_APPHEADER_CONTENT_JSON "appHeaderContent" +#define MSG_BODY_BYTE_BODY_APPHEADER_NAME_STR "appHeaderName" +#define MSG_BODY_BYTE_BODY_CONTENT_STR "body" +#define MSG_BODY_BYTE_BODY_CREATETIME_LINT "createTime" +#define MSG_BODY_BYTE_BODY_SYSTEM_HEADER_CONTENT_JSON "sysHeaderContent" + +#define MSG_BODY_RMB_TRACE_LOG_JSON "rmbTraceLog" +#define MSG_BODY_RMB_TRACE_LOG_LOG_POINT_STR "logPoint" +#define MSG_BODY_RMB_TRACE_LOG_ERR_CODE_STR "errCode" +#define MSG_BODY_RMB_TRACE_LOG_ERR_MSG_STR "errMsg" +#define MSG_BODY_RMB_TRACE_LOG_MESSAGE_STR "message" +#define MSG_BODY_RMB_TRACE_LOG_EXTFIELDS_STR "extFields" + +#define MSG_BODY_SYSTEM_JSON "sysHeader" +#define MSG_BODY_SYSTEM_BIZ_STR "bizSeqNo" +#define MSG_BODY_SYSTEM_SEQNO_STR "consumerSeqNo" +#define MSG_BODY_SYSTEM_SVRID_STR "consumerSvrId" +#define MSG_BODY_SYSTEM_ORGSYS_STR "orgSysId" +#define MSG_BODY_SYSTEM_CSMID_STR "consumerId" +#define MSG_BODY_SYSTEM_TIME_LINT "tranTimestamp" +#define MSG_BODY_SYSTEM_CSMDCN_STR "consumerDCN" +#define MSG_BODY_SYSTEM_ORGSVR_STR "orgSvrId" +#define MSG_BODY_SYSTEM_ORGID_STR "organizationId" +#define MSG_BODY_SYSTEM_VER_STR "version" +#define MSG_BODY_SYSTEM_UNIID_STR "uniqueId" +#define MSG_BODY_SYSTEM_CONLEN_INT "contentLength" +#define MSG_BODY_SYSTEM_MSGTYPE_INT "messageType" +#define MSG_BODY_SYSTEM_RRTYPE_INT "rrType" +#define MSG_BODY_SYSTEM_ACK_SEQ "ack_seq" +#define MSG_BODY_SYSTEM_RECVTYPE_INT "receiveMode" +#define MSG_BODY_SYSTEM_SENDTIME_LINT "sendTimestamp" +#define MSG_BODY_SYSTEM_RECVTIME_LINT "receiveTimestamp" +#define MSG_BODY_SYSTEM_REPLYTIME_LINT "replyTimestamp" +#define MSG_BODY_SYSTEM_REPLYRECEIVETIME_LINT "replyReceiveTimestamp" +#define MSG_BODY_SYSTEM_APITYPE_INT "apiType" +#define MSG_BODY_SYSTEM_LOGICTYPE_INT "logicType" +#define MSG_BODY_SYSTEM_SOCOID_STR "solCorrelationId" +#define MSG_BODY_SYSTEM_EXTFIELDS_STR "extFields" +#define MSG_BODY_SYSTEM_API_VERSION "rmbVersion" +#define MSG_BODY_SYSTEM_REQ_IP "req_ip" +#define MSG_BODY_SYSTEM_REQ_SYS "req_sys" +#define MSG_BODY_SYSTEM_REQ_DCN "req_dcn" +#define MSG_BODY_SYSTEM_REQ_IDC "req_idc" +#define MSG_BODY_SYSTEM_RSP_IP "rsp_ip" +#define MSG_BODY_SYSTEM_RSP_SYS "rsp_sys" +#define MSG_BODY_SYSTEM_RSP_DCN "rsp_dcn" +#define MSG_BODY_SYSTEM_RSP_IDC "rsp_idc" + +#define MSG_BODY_APP_JSON "appHeader" + +#define MSG_BODY_DEST_JSON "destinationContent" +#define MSG_BODY_DEST_NAME_STR "name" +#define MSG_BODY_DEST_TYPE_STR "type" +#define MSG_BODY_DEST_SORE_STR "serviceOrEventId" +#define MSG_BODY_DEST_SCENARIO_STR "scenario" +#define MSG_BODY_DEST_ANY_DCN_STR "anyDCN" +#define MSG_BODY_DEST_DCN_STR "dcnNo" +#define MSG_BODY_DEST_ORGID_STR "organizationId" +#define MSG_BODY_DEST_ORGFLAG_INT "organizationIdInputFlag" + +#define MSG_BODY_TTL_LINT "timeToLive" +#define MSG_BODY_CONTENT_STR "content" +#define MSG_BODY_REPLYTO_STR "replyTo" +#define MSG_BODY_CREATETIME_LINT "createTime" +#define MSG_BODY_DELIVERYTIME_INT "deliveryTimes" +#define MSG_BODY_RESENT_BOOL "resent" +#define MSG_BODY_COID_STR "correlationId" +#define MSG_BODY_DUP_BOOL "duplicated" +#define MSG_BODY_SYN_BOOL "syn" +#define LOG_ERROR_POINT "ON_ERROR" + + typedef struct StRmbMsg StRmbMsg; + + typedef struct StWemqThreadMsg + { + unsigned int m_iCmd; + + unsigned int m_iHeaderLen; + unsigned int m_iBodyLen; + char *m_pHeader; + char *m_pBody; + } StWemqThreadMsg; + +#define RMB_MAX_UNIQUE_NUMS 2048 + + typedef struct StUniqueIdList + { + char unique_id[50]; + char biz_seq[50]; + unsigned int timeout; + unsigned int flag; + unsigned long timeStamp; + } StUniqueIdList; + + typedef struct StUniqueIdList DataType; + + typedef struct array + { + DataType *Data; + int size, max_size; + void (*Constructor) (struct array *); //构造函数 + void (*Input) (DataType, struct array *); //输入数据 + int (*get_array_size) (struct array *); //获取arr的大小 + int (*return_index_value) (struct array *, int); + void (*Destructor) (struct array *); //析构函数 + } Array; + +#define RMB_MAX_ERR_MSG_FROM_ACCESS 1024 + +//wemq msg 最多4m +#define WEMQ_MSG_MSX_LENGTH (1 << 22) + + typedef struct stContextProxy + { + pthread_t mainThreadId; + pthread_t coThreadId; + + char *mPubRRBuf; + + //for rr + pthread_mutex_t rrMutex; + pthread_cond_t rrCond; + int iFlagForRR; + + //for event msg, wait for ack + pthread_mutex_t eventMutex; + pthread_cond_t eventCond; + int iFlagForEvent; + long iSeqForEvent; + + //for add listen + pthread_mutex_t regMutex; + pthread_cond_t regCond; + int iFlagForReg; + //for add listen result check + int iResultForReg; + + //for pub session connect + pthread_mutex_t pubMutex; + pthread_cond_t pubCond; + int iFlagForPub; + int iFlagForPublish; + + //for sub session connect + pthread_mutex_t subMutex; + pthread_cond_t subCond; + int iFlagForSub; + +// myhash_t* rrHashTable; + void *pubContext; + void *subContext; + + StRmbMsg *pReplyMsg; + + //StUniqueIdList *pUniqueListForRRAsyncNew; + //StUniqueIdList *pUniqueListForRRAsyncOld; + + Array pUniqueListForRRAsyncNew; + Array pUniqueListForRRAsyncOld; + + StUniqueIdList stUnique; + + //StUniqueIdList stUniqueListForRRAsync[RMB_MAX_UNIQUE_NUMS]; + //StUniqueIdList stUniqueListForRRAsyncOld[RMB_MAX_UNIQUE_NUMS]; + + //Array stUniqueListForRRAsync; + //Array stUniqueListForRRAsyncOld; + + int iFlagForRun; + unsigned long ulGoodByeTime; + unsigned long ulLastClearRRAysncMsgTime; + unsigned long ulLastPrintOldListIsEmpty; + int iFlagForRRAsync; + + //for goodbye + pthread_mutex_t goodByeMutex; + pthread_cond_t goodByeCond; + int iFlagForGoodBye; + + StWemqTopicList stTopicList; + STRUCT_WEMQ_KFIFO (StWemqThreadMsg, MAX_WEMQ_KFIFO_LENGTH) pubFifo; + STRUCT_WEMQ_KFIFO (StWemqThreadMsg, MAX_WEMQ_KFIFO_LENGTH) subFifo; + } stContextProxy; + + typedef struct StThreadArgs + { + stContextProxy *pStContextProxy; + int contextType; + } StThreadArgs; + +#define WEMQ_FIFO_SIZE (2 << 20) + + typedef struct WemqThreadCtx + { + STRUCT_WEMQ_KFIFO (StWemqThreadMsg, WEMQ_FIFO_SIZE) * m_ptFifo; + stContextProxy *m_ptProxyContext; + + //int m_iThreadId; + char *m_pRecvBuff; + char *m_pSendBuff; + + //cache msg which from user thread; + StWemqThreadMsg m_stWemqThreadMsg; + StWemqThreadMsg m_stHeartBeat; + StWemqThreadMsg m_stHelloWord; + StWemqThreadMsg m_stListen; + + int m_iWemqThreadMsgHandled; + +// StWemqHeader m_stWemqHeader; + StWeMQMSG m_stWeMQMSG; + StWemqTopicList *m_ptTopicList; + + //for epoll + int m_iEpollFd; + struct epoll_event m_stEv; + struct epoll_event *m_ptEvents; + + int m_iFlagForSeverBreak; + + SSL_CTX *sslCtx; + + int m_iSockFd; + SSL *ssl; + + int m_iSockFdNew; + SSL *sslNew; + + int m_iSockFdOld; + SSL *sslOld; + + int m_iLastState; + int m_iState; + int m_contextType; + + int m_iHeartBeatCount; + unsigned int m_uiHeartBeatCurrent; + struct timeval stTimeNow; + struct timeval stTimeLast; + struct timeval stTimeLastRecv; + + // proxy server 地址 + char m_cProxyIP[100]; + char m_cProxyIPOld[100]; + unsigned int m_uiProxyPort; + unsigned int m_uiProxyPortOld; + int m_iLocalPort; // socket local port + + pthread_t m_threadID; // current thread's ID + +// bool m_lRedirect; + int m_lRedirect; + char m_cRedirectIP[100]; + int m_iRedirectPort; + + } WemqThreadCtx; +//************************************************************************* + +//**************************rmb msg define********************************* + + enum RmbDestinationType + { + RMB_DEST_TOPIC = 0, + RMB_DEST_QUEUE, + }; + +#define RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN 1024 * 2 // 2K +#define RMB_SYSTEMHEADER_PROPERTY_MAX_LEN 1024 * 2 // 2K + + typedef struct StSystemHeader + { + char cBizSeqNo[50]; //全局唯一业务流水号 + char cConsumerSeqNo[50]; //服务消费者系统调用流水号 + char cOrgSysId[10]; //交易原始发起方系统编号 + char cConsumerSysId[10]; //服务消费者系统编号 + char cConsumerSysVersion[10]; //服务消费者的系统版本号 + char cConsumerSvrId[50]; //服务消费者服务器标示(服务器名或IP地址) + char cRmbVersion[10]; //rmb版本号 + + char cOrgSvrId[50]; + char cUniqueId[50]; //unique id + char cConsumerDcn[10]; //服务消费者所在DCN + unsigned long ulTranTimeStamp; //交易发起时间戳 + char cAppHeaderClass[50]; //类名 + char cOrgId[10]; //法人号 + int flag; + + unsigned long ulSendTime; //发送时间 + unsigned long ulReceiveTime; //接收时间 + unsigned long ulReplyTime; //回包时间 + unsigned long ulReplyReceiveTime; //回包接收时间 + + unsigned long ulMessageDate; + + int iReceiveMode; + + int iContentLength; + char cExtFields[RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN]; + char cProperty[RMB_SYSTEMHEADER_PROPERTY_MAX_LEN]; + int iSetSysVersionFlag; + } StSystemHeader; + +#define REQ_BORN_TIMESTAMP "req_born_timestamp" +#define REQ_STORE_TIMESTAMP "req_store_timestamp" +#define REQ_LEAVE_TIMESTAMP "req_leave_timestamp" +#define REQ_ARRIVE_TIMESTAMP "req_arrive_timestamp" + +#define RSP_BORN_TIMESTAMP "rsp_born_timestamp" +#define RSP_STORE_TIMESTAMP "rsp_store_timestamp" +#define RSP_LEAVE_TIMESTAMP "rsp_leave_timestamp" +#define RSP_ARRIVE_TIMESTAMP "rsp_arrive_timestamp" + + typedef struct StAppHeader + { + char cTransCode[8]; // + char cSourceChannelType[32]; // + char cWordStationId[4]; // + } StAppHeader; + + typedef struct StDestination + { + int iDestType; //target type: 0: topic 1: queue + char cDestName[200]; + } StDestination; + + typedef struct StFlow StFlow; + +//包类型分类 + enum C_RMB_PKG_TYPE + { + ALL_TYPE_RMB = 0, //所有类型 + QUEUE_PKG = 1, //queue上的消息,一般为请求 + RR_TOPIC_PKG = 2, //RR的回包 + BROADCAST_TOPIC_PKG = 3, //广播包 + MANAGE_TOPIC_PKG = 4, //RMB内部管理topic包 + NEW_LOGIC_RECEIVE = 5, + NEW_LOGIC_SEND = 6, + }; + +//包来源分类 + enum C_RMB_LOGIC_TYPE + { + REQ_PKG_IN = 1, + RSP_PKG_IN = 2, + EVENT_PKG_IN = 3, + REQ_PKG_OUT = 4, + RSP_PKG_OUT = 5, + EVENT_PKG_OUT = 6, + + REQ_PKG_IN_WEMQ = 7, + RSP_PKG_IN_WEMQ = 8, + EVENT_PKG_IN_WEMQ = 9, + REQ_PKG_OUT_WEMQ = 10, + RSP_PKG_OUT_WEMQ = 11, + EVENT_PKG_OUT_WEMQ = 12, + MANAGE_PKG_IN_WEMQ = 13, + }; + + enum C_RMB_MESSAGE_TYPE + { + RMB_REQ_MSG = 1, + RMB_RSP_MSG = 2, + RMB_EVENT_MSG = 3, + }; + +//rmb转发包的方式 + enum UDP_OR_MQ + { + MSG_IPC_UDP = 0, + MSG_IPC_MQ = 1, + }; + + enum RMB_API_YPE + { + JAVA_TYPE = 1, + C_TYPE = 2, + JAVA_TYPE_WEMQ = 3, + C_TYPE_WEMQ = 4, + }; + + enum RMB_CONTEXT_TYPE + { + RMB_CONTEXT_TYPE_SUB = 0, + RMB_CONTEXT_TYPE_PUB = 1 + }; + +//typedef struct StRmbMsg + struct StRmbMsg + { + //sessionIndex for wemq + unsigned int uiSessIndex; + unsigned int uiFlowIndex; + + //pkg type + char cPkgType; //收到包的类型 + char cLogicType; //消息来源 + char cApiType; //apiType, enum RMB_API_YPE + StSystemHeader sysHeader; + StDestination dest; + StDestination replyTo; + unsigned long ulMsgId; + unsigned long ulMsgLiveTime; + char isDyedMsg[10]; + + //for receive msg + //char cServiceId[8]; + //char cScenario[2]; + + //char cAppHeader[MAX_APPHEADER_LENGTH]; + char *cAppHeader; + int iMallocAppHeaderLength; + int iAppHeaderLen; + + //char cContent[MAX_MSG_CONTENT_SIZE]; + char *cContent; + int iMallocContentLength; + int iContentLen; + + char cCorrId[MAX_COMMON_SIZE]; + int iCorrLen; + + //msg src + int iEventOrService; //0 event;1 service + char strTargetDcn[10]; + char strServiceId[10]; + char strScenarioId[5]; + + //for gsl + char strTargetOrgId[10]; + int iFLagForOrgId; + + //for flag check + int flag; + + int iMsgMode; //pub:send msg to wemq or solace sub:recv msg from wemq or solace + + char strLogBuf[1024]; +//}StRmbMsg; + }; + +//************for mq + typedef void (*rmb_callback_func) (const char *, const int, void *); + typedef int (*rmb_callback_func_v2) (const char *, const int, void *); +#define MAX_MQ_NUMS 10 +#define MAX_FIFO_PATH_NAME_LEN 200 +#define MAX_MQ_PKG_SIZE 10000000 +//static const unsigned int C_RMB_MQ_HEAD_SIZE = 2 * sizeof(unsigned int); +#define C_RMB_MQ_HEAD_SIZE 2 * sizeof(unsigned int) +#define C_RMB_MQ_PKG_HEAD_SIZE 2 * sizeof(unsigned int) +//static const unsigned int C_RMB_MQ_PKG_HEAD_SIZE = 2 * sizeof(unsigned int); + + typedef struct StRmbMq + { + unsigned int uiShmkey; + unsigned long ulShmId; + unsigned int uiShmSize; + + //head + tail + real data + char *pMqData; + unsigned int *pHead; + unsigned int *pTail; + + //real data + char *pBlock; + unsigned int uiBlockSize; + + } StRmbMq; + + typedef struct StRmbFifo + { + int iFd; + char strPath[MAX_FIFO_PATH_NAME_LEN]; + } StRmbFifo; + + typedef struct StRmbQueue + { + unsigned int uiSize; + + //head + tail + real data + char *pData; + unsigned int *pHead; + unsigned int *pTail; + + //real data + char *pBlock; + unsigned int uiBlockSize; + } StRmbQueue; + + typedef struct StRmbPipe + { + int fd[2]; + int r_fd; + int w_fd; + } StRmbPipe; + + typedef struct StMqInfo + { + StRmbMq *mq; + StRmbFifo *fifo; + + //for wemq + StRmbQueue *que; + StRmbPipe *pipe; + + int iIndex; //offset in vector + int iMsgType; //iPkgType,1 queue msg;2 rr topic msg;3 broadcast msg;4 manage msg + + rmb_callback_func func; + rmb_callback_func_v2 funcForNew; + void *args; + + //for epoll + int active; + + //for notify num + int iCount; + unsigned int uiLastCheckTime; + + int iMergeNotifyFLag; //0:not marge 1:marge + int iNotifyFactor; //the factor of notify + + pthread_mutex_t queMutex; + } StMqInfo; + + enum RmbMqIndex + { + req_mq_index = 1, + rr_rsp_mq_index = 2, + broadcast_mq_index = 3, + manage_mq_index = 4, + +// wemq_req_mq_index = 5, +// wemq_rr_rsp_mq_index = 6, +// wemq_broadcast_mq_index = 7, +// wemq_manage_mq_index = 8, + }; + +//for mq notify + typedef struct StRmbMqFifoNotify + { + StMqInfo vecMqInfo[MAX_MQ_NUMS]; + int iMqNum; + + StMqInfo *mqIndex[MAX_MQ_NUMS]; //see define of RmbMqIndex + //for select + fd_set readFd; + fd_set tmpReadFd; + struct timeval tv; + int iMaxFd; + + //for epoll + int iEpollFd; + + char *pBuf; + unsigned int uiBufLen; + + } StRmbMqFifoNotify; + +/////////////////////////////// + + typedef struct StContext StContext; + +//*************************context************************ + +//context的基本定义 + struct StContext + { + // for solace + unsigned int uiInitFlag; + + //for receive msgs + StRmbMsg *pReceiveMsg; + StRmbMsg *pReceiveMsgForRR; + StRmbMsg *pReceiveMsgForBroadCast; + + StRmbMsg *pReceiveWemqMsg; + StRmbMsg *pReceiveWemqMsgForRR; + StRmbMsg *pReceiveWemqMsgForBroadCast; + + //for receive msgs + char *pPkg; + unsigned int uiPkgLen; + + //for wemq + char *pWemqPkg; + unsigned int uiWemqPkgLen; + + char *pWemqPkgForRRAsync; + unsigned int uiWemqPkgForRRAsyncLen; + + //********UDP************* + //for rev req or broadcast + int iSocketForReq; + struct sockaddr_in tmpReqAddr; + + //for rev reply + int iSocketForRsp; + struct sockaddr_in tmpReplyAddr; + + //for rev broadcast + int iSocketForBroadcast; + struct sockaddr_in tmpBroadcastAddr; + + //*******MQ*************** + StRmbMqFifoNotify fifoMq; + + unsigned int uiNowTime; + + //sub or pub + void *pFather; + + //****for wemq + unsigned int uiInitWemqFlag; + + //for wemq proxy + stContextProxy *pContextProxy; + //sub or pub; + int contextType; + }; + +//********broadcast********* + typedef struct StBroadcastNode + { + char strServiceId[10]; + char strScenarioId[5]; + char cConsumerSysId[10]; + char cReserve[2]; + } StBroadcastNode; + +//********queue节点*********** + typedef struct StQueueNode + { + char cQueueName[30]; + int iQueueSize; + int iQueueUnackSize; + + } StQueueNode; + + typedef struct StQueueName + { + char cQueueName[30]; + } StQueueName; + + typedef struct StServiceStatus + { + char strTargetOrgId[10]; + char strServiceId[10]; + char strScenarioId[5]; + char cFlagForOrgId; + + char cResult; + char cRouteFlag; + char strTargetDcn[10]; + unsigned long ulGetTimes; + unsigned long ulInvalidTime; + } StServiceStatus; + + typedef struct StRmbConfig + { + char strConfigFile[500]; + + char cConsumerSysId[10]; + char cConsumerSysVersion[10]; + char cConsumerSvrId[100]; + char cOrgSvrId[50]; + //char cUniqueId[100]; + char cConsumerDcn[10]; + + //主机名 + char cHostName[100]; + char cHostIp[50]; + unsigned int uiPid; + + //log + int iLogLevel; + //RmbLogFile stLog; + char logFileName[200]; + int iLogFileNums; + int iLogFileSize; + int iLogShiftType; + + StRmbLog gRmbLog; + + //for solace api init + unsigned int uiIsInitSolaceApi; + //solace + int iSwitchForSolaceLog; + char strSolaceLog[100]; + int iSolaceLogLevel; + + //for connect success timeout + int createConnectionTimeOut; + + //debug switch + int iDebugSwitch; + + //queue config + StQueueNode queueNodeList[5000]; + int iQueueListSize; + + StBroadcastNode broadNodeList[5000]; + int iBroadListSize; + + //for browser + pthread_mutex_t configMutex; + pthread_cond_t configCond; + int iFlag; + + //for mergeq for gsl + pthread_mutex_t mergeqForGslMutex; + pthread_cond_t mergeqForGslCond; + int iFlagForMerge; + int iMergeQueue; + //for merge queue + pthread_mutex_t mergeQueueMutex; + + //for log + pthread_mutex_t configLog; + + //for send white list +// pthread_mutex_t sendWhiteListMutex; + + //for debug print + char *pLogBuf; + + //for manage session + int iManageFlag; //0 表示还没有, 1表示有 + + StQueueName fullQueueList[3000]; //queue + int iFullNums; + + //for flag + int iFlagForReq; //0:UDP,1:MQ + int iFlagForRRrsp; //0:UDP,1:MQ + int iFlagForBroadCast; //0:UDP,1:MQ + int iFlagForManage; //0:UDP,1:MQ + + //每次处理的个数 + int iEveryTimeProcessNum; + + //提醒的try间隔 + int iNotifyCheckSpan; + + //for req mq + char strFifoPathForReq[128]; + unsigned int uiShmKeyForReq; + unsigned int uiShmSizeForReq; + + //for rsp + char strFifoPathForRRrsp[128]; + unsigned int uiShmKeyForRRrsp; + unsigned int uiShmSizeForRRrsp; + + //for broadcast + char strFifoPathForBroadcast[128]; + unsigned int uiShmKeyForBroadcast; + unsigned int uiShmSizeForBroadcast; + + //flag + //是否合并通知的开关 + int iFLagForMergeNotify; + + //orgId + char strOrgId[10]; + + //last error + char _lastError[300]; + + //是否允许发送的开关 + int iFlagForPublish; + unsigned long ulLastStopTime; + unsigned long ulLastAllowTime; + char cLastMsg[50]; + + //rmb的启动时间 + unsigned long ulStartTime; //rmb init time + + //RR info + unsigned int uiSendRRMsgNums; + unsigned int uiSendRRMsgError; + + //Event info + unsigned int uiSendEventMsg; + unsigned int uiSendEventMsgError; + + //AyncRR + unsigned int uiSendAyncRRMsg; + unsigned int uiSendAyncRRMsgError; + + //receiveMsg + unsigned int uiReceiveServiceReqMsg; + unsigned int uiReceiveAyncRRReply; + unsigned int uiReceiveEventMsg; + + StServiceStatus serviceStatusList[MAX_SERVICE_STATUS_CACHE_NUMS]; + int iCacheServiceNums; + + int iCacheTimeoutTime; + int iCacheSuccTimeoutTime; //gsl query success, timeout default is 600s + int iCacheFailedTimeoutTime; //gsl query failed, timeout default is 30s + + //timtout + unsigned long ulNowTtime; + + //exit timtout + unsigned long ulExitTimeOut; + + //for rmb proxy worker + int iRmbMode; + + int iWorkerSendBufSize; + + //for reload cfg + //signal1 + int iSwitchForSignal1; + //signal2 + int iSwitchForSignal2; + + //for ack + int ackTimers; + int ackThresHold; + + //for query timeout + int iQueryTimeout; + + //for sub broadcast LVQ + unsigned int uiIsBroadcastLVQ; + + //for msg trans by solace timeout :daxin + int iCommonTimeOut; + //for rmb period stat log + int iStatPeriod; + //get group topic status time + int iGetGroupTopicTime; + //get send white list time + int iGetSendWhiteListTime; + + //for clean merge q thread + pthread_t pid_merge; + int flag_merge; + + // logServer log switch for user + int iLogserverSwitch; + //logServer log switch for api + int iApiLogserverSwitch; + //rmb mode: wemq + char cRmbMode[10]; + int iConnWemq; + + //gsl control + int iReqGsl; + + //for config center + char cConfigIp[256]; + int iConfigPort; + int iConfigTimeout; + int configIpPosInArr; + char ConfigAddr[512]; +// char cWemqSavePath[1024]; + + int tlsOnoff; + + //local IDC config + char cRegion[10]; + + int iFlagForLoop; + + //for proxyContext + int iProxyContextNums; + void *pProxyContext; + + //for mode worker heart beat; + int heartBeatPeriod; + int heartBeatTimeout; + + //for get access ip + int getAccessIpPeriod; + + //for access ack + int accessAckTimeOut; + + //for rr async + int rrAsyncTimeOut; + + //for access goodbye + int goodByeTimeOut; + + // wemq-access 配置中心服务器 + int iWemqUseHttpCfg; // 是否启用Http配置中心 + //for default tcp + char cWemqProxyIp[100]; + unsigned int cWemqProxyPort; + int iWemqTcpConnectRetryNum; // 连接wemq-access重试次数 + int iWemqTcpConnectDelayTime; // 每次重连间隔时间(ms) + + int iWemqTcpConnectTimeout; // 每次TCP连接超时时间 + int iWemqTcpSocketTimeout; // TCP socket 超时时间 + + //for topic + int iNormalTimeout; // 监听topic超时时间(ms), default is:120000 + + //for wemq user/passwd + char cWemqUser[100]; + char cWemqPasswd[100]; + + int mqIsEmpty; + + char strDepartMent[20]; + } StRmbConfig; + + typedef struct RmbPythonConfig + { + //for req mq + char strFifoPathForReq[128]; + unsigned int uiShmKeyForReq; + unsigned int uiShmSizeForReq; + + //for rsp + char strFifoPathForRRrsp[128]; + unsigned int uiShmKeyForRRrsp; + unsigned int uiShmSizeForRRrsp; + + //for broadcast + char strFifoPathForBroadcast[128]; + unsigned int uiShmKeyForBroadcast; + unsigned int uiShmSizeForBroadcast; + } RmbPythonConfig; + + enum MQ_STATUS + { + MQ_INIT = 0, + MQ_IS_NOT_EMPTY, + MQ_IS_EMPTY + }; + +//灰度完成queue的场景ID +#define GRAY_COMPLETE_SCENE "FR" + + enum TOPIC_STATUS + { + QUEUE_NOT_GRAY = 0, + QUEUE_GRAY_INIT, + QUEUE_GRAY_NOT_COMPLETE, + QUEUE_GRAY_COMPLETE + }; + + typedef struct StRmbListenQueueInfo + { + char cDcn[5]; + char cServiceId[10]; + char cScenarioId[5]; + } st_rmb_queue_info; + +//rmb topic info + typedef struct StRmbTopicInfo + { + char cServiceId[10]; + char cScenarioId[5]; + char cTopicGroup[32]; + char cTopicStatus[3]; + int flag; + } StRmbTopicInfo; + + extern StRmbConfig *pRmbStConfig; + extern char cManageTopic[30]; + extern char cQueueFullTopic[30]; + extern char cLogLevelTopic[30]; +///////////////add by wan + extern char cPublishCheck[30]; +///////////////////////////// + extern StContext *g_pStContextArry[MAX_RMB_CONTEXT]; +#define LOGRMB(loglevel,fmt, args...) {LogRmb(loglevel, "[%s:%d(%s)]["fmt"]", __FILE__, __LINE__, __FUNCTION__, ## args);\ + if(loglevel==RMB_LOG_ERROR) snprintf(pRmbStConfig->_lastError, sizeof(pRmbStConfig->_lastError)-1, fmt, ## args);} + +//****common tool******* +#define RMB_MGS_PRINT_P(p) p->cConsumerSysId,p->cConsumerSysId,p->cConsumerSysId, +#define RMB_MAX(a,b) (a>b)?a:b +#define RMB_MIN(a,b) (a len){return -1;} +#define RMB_LEN_CHECK(a,len); if(strlen(a) != len){rmb_errno=RMB_ERROR_ARGV_LEN_ERROR;return rmb_errno;} + +//#define RMB_CHECK_POINT_NULL(a,b); if((void*)a == NULL) {LOGRMB(RMB_LOG_ERROR,"%s is NULL!", b);return -1;} +#define RMB_CHECK_POINT_NULL(a,b); if((void*)a == NULL) {LOGRMB(RMB_LOG_ERROR,"%s is NULL!", b);rmb_errno=RMB_ERROR_ARGV_NULL;return RMB_ERROR_ARGV_NULL;} +//end +#define RMB_MEMSET(a); memset(&a, 0, sizeof(a)); + +#define RMB_ADD_SESSION_PROPERTY(a,b,c); sprintf(a->cSessionProps[a->uiPropIndex], "%s", b);\ + a->vecPSessProps[a->uiPropIndex] = a->cSessionProps[a->uiPropIndex];\ + a->uiPropIndex++;\ + sprintf(a->cSessionProps[a->uiPropIndex], "%s", c);\ + a->vecPSessProps[a->uiPropIndex] = a->cSessionProps[a->uiPropIndex];\ + a->uiPropIndex++; + +#define RMB_ADD_FLOW_PROPERTY(a,b,c); sprintf(a->cFlowProps[a->uiPropIndex], "%s", b);\ + a->vecPFlowProps[a->uiPropIndex] = a->cFlowProps[a->uiPropIndex];\ + a->uiPropIndex++;\ + sprintf(a->cFlowProps[a->uiPropIndex], "%s", c);\ + a->vecPFlowProps[a->uiPropIndex] = a->cFlowProps[a->uiPropIndex];\ + a->uiPropIndex++; + +#define RMB_ADD_FLOW_PROPERTY_INT(a,b,c); sprintf(a->cFlowProps[a->uiPropIndex], "%s", b);\ + a->vecPFlowProps[a->uiPropIndex] = a->cFlowProps[a->uiPropIndex]; \ + a->uiPropIndex++; \ + sprintf(a->cFlowProps[a->uiPropIndex], "%d", c);\ + a->vecPFlowProps[a->uiPropIndex] = a->cFlowProps[a->uiPropIndex];\ + a->uiPropIndex++; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_errno.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_errno.h new file mode 100644 index 0000000000..6f7d7aa9fe --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_errno.h @@ -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. + +#ifndef __RMB_ERRNO_H__ +#define __RMB_ERRNO_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + + extern int *rmb_error (void) __attribute__ ((__const__)); + +#define rmb_errno (*rmb_error()) + + struct rmb_err_msg + { + int err_no; + const char *err_msg; + }; + +#define RMB_MAX_ERR_NUMS 500 +#define RMB_ERROR_BASE_BEGIN 10000 + +//错误码列表 +#define RMB_ERROR_ARGV_NULL 10001 //参数为空 +#define RMB_ERROR_ARGV_LEN_ERROR 10002 //参数长度错误 +#define RMB_ERROR_MALLOC_FAIL 10003 //申请内存失败 +#define RMB_ERROR_INIT_CONTEXT_FAIL 10004 //初始化context失败 +#define RMB_ERROR_MSG_MISSING_PART 10005 //发送RMB消息必要字段缺少 +#define RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG 10006 //RMB同步接口不允许发送异步消息 +#define RMB_ERROR_EVENT_INTERFACE_CAN_NOT_SEND_RR_MSG 10007 //RMB异步接口不允许发送同步消息 +#define RMB_ERROR_NOW_CAN_NOT_SEND_MSG 10008 //现在禁止发送消息 +#define RMB_ERROR_QUEUE_FULL 10009 //该topic已queue满,不允许发送 +#define RMB_ERROR_GSL_SERVICE_ID_NULL 10010 //GSL服务id为空 +#define RMB_ERROR_GSL_SERVICE_ID_ERROR 10011 //GSL服务id路由失败 +#define RMB_ERROR_GSL_SVR_ERROR 10012 //GSL服务器返回失败 +#define RMB_ERROR_REQ_GSL_ERROR 10013 //请求GSL服务失败 +#define RMB_ERROR_MSG_UUID_FAIL 10014 //RMB消息生成UUID失败 +#define RMB_ERROR_MSG_SET_SYSTEMHEADER_FAIL 10015 //RMB消息初始化为SOLACE消息时设置systemHeader失败 +#define RMB_ERROR_SEND_GET_SESSION_FAIL 10016 //发送消息时,获取可用session失败 +#define RMB_ERROR_SEND_EVENT_MSG_FAIL 10017 //发送异步消息失败 +#define RMB_ERROR_SEND_RR_MSG_FAIL 10018 //发送同步消息失败 +#define RMB_ERROR_SEND_RR_MSG_TIMEOUT 10019 //发送同步消息超时 +#define RMB_ERROR_REPLY_TO_NULL 10020 //RR请求消息缺少replyTo,不允许reply +#define RMB_ERROR_REPLY_FAIL 10021 //回复消息失败 +#define RMB_ERROR_SESSION_CONNECT_FAIL 10022 //session连接失败--->连接session失败,请检查rmb配置文件是否正确 +#define RMB_ERROR_SESSION_RECONNECT_FAIL 10023 //session重连失败 +#define RMB_ERROR_SESSION_DESTORY_FAIL 10024 //session销毁失败 +#define RMB_ERROR_SESSION_NUMS_LIMIT 10025 //该类型session连接数已达上限 +#define RMB_ERROR_LISTEN_QUEUE_NOT_EXIST 10026 //监听queue失败,不存在该queue +#define RMB_ERROR_LISTEN_QUEUE_FAIL 10027 //监听queue失败 +#define RMB_ERROR_FLOW_DESTORY_FAIL 10028 //flow销毁失败 +#define RMB_ERROR_LISTEN_TOPIC_FAIL 10029 //监听topic失败 +#define RMB_ERROR_INIT_MQ_FAIL 10030 //初始化消息通信MQ失败 +#define RMB_ERROR_INIT_FIFO_FAIL 10031 //初始化通知FIFO失败 +#define RMB_ERROR_INIT_UDP_FAIL 10032 //初始化UDP失败 +#define RMB_ERROR_INIT_EPOLL_FAIL 10033 //初始化Epoll失败 +#define RMB_ERROR_MQ_NUMS_LIMIT 10034 //添加MQ数量超过上限 +#define RMB_ERROR_ENQUEUE_MQ_FAIL 10035 //消息入队MQ失败 +#define RMB_ERROR_DEQUEUE_MQ_FAIL 10036 //消息出队MQ失败 +#define RMB_ERROR_MSG_2_BUF_FAIL 10037 //RMB消息转为Buf失败 +#define RMB_ERROR_BUF_2_MSG_FAIL 10038 //Buf转RMB消息失败 +#define RMB_ERROR_MSG_SET_CONTENT_TOO_LARGE 10039 //RMB消息设置Content过大 +#define RMB_ERROR_MSG_SET_APPHEADER_TOO_LARGE 10040 //RMB消息设置AppHeader过大 +#define RMB_ERROR_MSG_TTL_0 10041 //RMB消息设置存活时间必须大于0 +#define RMB_ERROR_RCV_MSG_GET_CONTENT_FAIL 10042 //RMB接收消息获取Content失败 +#define RMB_ERROR_RCV_MSG_GET_BINARY_FAIL 10043 //RMB接收消息获取BinaryAttachment失败 +#define RMB_ERROR_RCV_MSG_CONTENT_TOO_LARGE 10044 //RMB接收消息Content过大 +#define RMB_ERROR_RCV_MSG_APPHEADER_TOO_LARGE 10045 //RMB接收消息AppHeader过大 +#define RMB_ERROR_MANAGE_MSG_PKG_ERROR 10046 //RMB管理消息包格式错误 +#define RMB_ERROR_MANAGE_MSG_PKG_CHECK_FAIL 10047 //RMB管理消息鉴权失败 +#define RMB_ERROR_CONTEXT_CREATE_FAIL 10048 //CONTEXT创建失败 +#define RMB_ERROR_FIFO_PARA_ERROR 10049 //FIFO参数错误 +#define RMB_ERROR_SHM_PARA_ERROR 10050 //SHM参数错误 +#define RMB_ERROR_SEND_FIFO_NOTIFY_ERROR 10051 //fifo发送通知失败 +#define RMB_ERROR_FLOW_NUMS_LIMIT 10052 //flow数目限制 +#define RMB_ERROR_MSG_GET_SYSTEMHEADER_ERROR 10053 //消息systemHeader错误 +#define RMB_ERROR_RMB_MSG_2_SOLACE_MSG_ERROR 10054 //copy rmb msg 2 solace msg error +#define RMB_ERROR_SOLACE_MSG_2_RMB_MSG_ERROR 10055 //copy solace msg 2 rmb msg error +#define RMB_ERROR_NO_AVAILABLE_SESSION 10056 //没有可用的session +#define RMB_ERROR_NO_BROADCAST_SESSION 10057 //没有可用的添加广播的session +#define RMB_ERROR_NO_AVAILABLE_CONTEXT 10058 //没有可用的context +#define RMB_ERROR_SET_FLOW_PROPETY 10059 //设置flow属性错误 +#define RMB_ERROR_ACK_MSG_FAIL 10060 //ack消息失败 +#define RMB_ERROR_LOGIC_NOTIFY_INIT 10061 //logic进程notify初始化失败 +#define RMB_ERROR_SESSION_ADD_FAIL 10062 //增加session失败 +#define RMB_ERROR_WORKER_NUMS_LIMIT 10063 //worker数量限制 +#define RMB_ERROR_BUF_NOT_ENOUGH 10064 //buf不够存储 +#define RMB_ERROR_STOP_FLOW_ERROR 10065 //停止flow收消息失败 +#define RMB_ERROR_DEQUEUE_MQ_EMPTY 10066 //消息队列出队为空 +#define RMB_ERROR_REMOVE_TOPIC_FAIL 10067 //删除监听topic失败 + +//proxy add +#define RMB_NOT_REGISTER_WORKER 10068 //worker还未注册 +#define RMB_SEND_MSG_ERROR_TYPE 10069 //发送消息错误的类型 +#define RMB_MSG_DECODE_ERROR 10070 //worker到proxy消息decode错误 +#define RMB_WORKER_BUF_FULL 10071 //worker满了 + +#define RMB_ERROR_CREATE_THREAD_FAIL 10072 //创建线程失败 +#define RMB_ERROR_ENCODE_FAIL 10073 //Encode失败 +#define RMB_ERROR_DECODE_FAIL 10074 //Decode失败 +#define RMB_ERROR_RR_RSP_NOTIFY_ERROR 10075 //RR回包唤醒错误 +#define RMB_ERROR_WORKER_REGISTER_ERROR 10076 //注册worker失败 +#define RMB_ERROR_WORKER_WINDOW_FULL 10077 //worker发送队列已满; +#define RMB_ERROR_WORKER_PUT_FIFO_ERROR 10078 //put msg into fifo error + +#define RMB_ERROR_START_CALL_FAIL 10079 +#define RMB_ERROR_END_CALL_FAIL 10080 +#define RMB_ERROR_ENTRY_FAIL 10081 +#define RMB_ERROR_EXIT_FAIL 10082 +#define RMB_ERROR_TOPIC_COUNT_TOO_LARGE 10083 //流控比时,topic个数超过最大个数 +#define RMB_ERROR_CLIENT_GOODBYE_TIMEOUT 10084 //客户端退出超时 + + void init_error (); + + const char *get_rmb_last_error (); + + void rmb_reset_error (); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_http_client.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_http_client.h new file mode 100644 index 0000000000..c916285e1c --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_http_client.h @@ -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. + +#ifndef __RMB_HTTP_CLIENT_H +#define __RMB_HTTP_CLIENT_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + struct rmb_http_buffer + { + size_t len; + char *data; + }; + +// timeout: ms + int rmb_http_easy_get (const char *url, void *buffer, long timeout); +//int rmb_http_easy_post(char* url, char* post_data, size_t len, void* buffer, size_t size, size_t* used, long timeout); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_list.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_list.h new file mode 100644 index 0000000000..0dd1c016d9 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_list.h @@ -0,0 +1,564 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * copy from linux_list.h + */ + +#ifndef RMB_LIST_H_ +#define RMB_LIST_H_ + +#include + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +typedef struct rmb_st_list +{ + struct st_list *prev, *next; + void *data; +} RMB_LIST; + +struct rmb_list_head +{ + struct rmb_list_head *next, *prev; +}; + +#define RMB_LIST_HEAD_INIT(name) { &(name), &(name) } + +#define RMB_LIST_HEAD(name) \ + struct rmb_list_head name = RMB_LIST_HEAD_INIT(name) + +static inline void RMB_INIT_LIST_HEAD (struct rmb_list_head *list) +{ + list->next = list; + list->prev = list; +} + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __rmb_list_add (struct rmb_list_head *newNode, + struct rmb_list_head *prev, + struct rmb_list_head *next) +{ + next->prev = newNode; + newNode->next = next; + newNode->prev = prev; + prev->next = newNode; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void rmb_list_add (struct rmb_list_head *newNode, + struct rmb_list_head *head) +{ + __rmb_list_add (newNode, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void rmb_list_add_tail (struct rmb_list_head *newNode, + struct rmb_list_head *head) +{ + __rmb_list_add (newNode, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __rmb_list_del (struct rmb_list_head *prev, + struct rmb_list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty() on entry does not return true after this, the entry is + * in an undefined state. + */ +static inline void rmb_list_del (struct rmb_list_head *entry) +{ + __rmb_list_del (entry->prev, entry->next); + entry->next = NULL; + entry->prev = NULL; +} + +/** + * list_replace - replace old entry by new one + * @old : the element to be replaced + * @new : the new element to insert + * + * If @old was empty, it will be overwritten. + */ +static inline void rmb_list_replace (struct rmb_list_head *old, + struct rmb_list_head *newNode) +{ + newNode->next = old->next; + newNode->next->prev = newNode; + newNode->prev = old->prev; + newNode->prev->next = newNode; +} + +static inline void rmb_list_replace_init (struct rmb_list_head *old, + struct rmb_list_head *newNode) +{ + rmb_list_replace (old, newNode); + RMB_INIT_LIST_HEAD (old); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void rmb_list_del_init (struct rmb_list_head *entry) +{ + __rmb_list_del (entry->prev, entry->next); + RMB_INIT_LIST_HEAD (entry); +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void rmb_list_move (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + __rmb_list_del (list->prev, list->next); + rmb_list_add (list, head); +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void rmb_list_move_tail (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + __rmb_list_del (list->prev, list->next); + rmb_list_add_tail (list, head); +} + +/** + * list_is_last - tests whether @list is the last entry in list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int rmb_list_is_last (const struct rmb_list_head *list, + const struct rmb_list_head *head) +{ + return list->next == head; +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int rmb_list_empty (const struct rmb_list_head *head) +{ + return head->next == head; +} + +/** + * list_empty_careful - tests whether a list is empty and not being modified + * @head: the list to test + * + * Description: + * tests whether a list is empty _and_ checks that no other CPU might be + * in the process of modifying either member (next or prev) + * + * NOTE: using list_empty_careful() without synchronization + * can only be safe if the only activity that can happen + * to the list entry is list_del_init(). Eg. it cannot be used + * if another CPU could re-list_add() it. + */ +static inline int rmb_list_empty_careful (const struct rmb_list_head *head) +{ + struct rmb_list_head *next = head->next; + return (next == head) && (next == head->prev); +} + +/** + * list_is_singular - tests whether a list has just one entry. + * @head: the list to test. + */ +static inline int rmb_list_is_singular (const struct rmb_list_head *head) +{ + return !rmb_list_empty (head) && (head->next == head->prev); +} + +static inline void __rmb_list_cut_position (struct rmb_list_head *list, + struct rmb_list_head *head, + struct rmb_list_head *entry) +{ + struct rmb_list_head *new_first = entry->next; + list->next = head->next; + list->next->prev = list; + list->prev = entry; + entry->next = list; + head->next = new_first; + new_first->prev = head; +} + +/** + * list_cut_position - cut a list into two + * @list: a new list to add all removed entries + * @head: a list with entries + * @entry: an entry within head, could be the head itself + * and if so we won't cut the list + * + * This helper moves the initial part of @head, up to and + * including @entry, from @head to @list. You should + * pass on @entry an element you know is on @head. @list + * should be an empty list or a list you do not care about + * losing its data. + * + */ +static inline void rmb_list_cut_position (struct rmb_list_head *list, + struct rmb_list_head *head, + struct rmb_list_head *entry) +{ + if (rmb_list_empty (head)) + return; + if (rmb_list_is_singular (head) && (head->next != entry && head != entry)) + return; + if (entry == head) + RMB_INIT_LIST_HEAD (list); + else + __rmb_list_cut_position (list, head, entry); +} + +static inline void __rmb_list_splice (const struct rmb_list_head *list, + struct rmb_list_head *prev, + struct rmb_list_head *next) +{ + struct rmb_list_head *first = list->next; + struct rmb_list_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +/** + * list_splice - join two lists, this is designed for stacks + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void rmb_list_splice (const struct rmb_list_head *list, + struct rmb_list_head *head) +{ + if (!rmb_list_empty (list)) + __rmb_list_splice (list, head, head->next); +} + +/** + * list_splice_tail - join two lists, each list being a queue + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void rmb_list_splice_tail (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + if (!rmb_list_empty (list)) + __rmb_list_splice (list, head->prev, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void rmb_list_splice_init (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + if (!rmb_list_empty (list)) + { + __rmb_list_splice (list, head, head->next); + RMB_INIT_LIST_HEAD (list); + } +} + +/** + * list_splice_tail_init - join two lists and reinitialise the emptied list + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * Each of the lists is a queue. + * The list at @list is reinitialised + */ +static inline void rmb_list_splice_tail_init (struct rmb_list_head *list, + struct rmb_list_head *head) +{ + if (!rmb_list_empty (list)) + { + __rmb_list_splice (list, head->prev, head); + RMB_INIT_LIST_HEAD (list); + } +} + +/** +* container_of - cast a member of a structure out to the containing structure +* @ptr: the pointer to the member. +* @type: the type of the container struct this is embedded in. +* @member: the name of the member within the struct. +* +*/ + +#define rmb_container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define rmb_list_entry(ptr, type, member) \ + rmb_container_of(ptr, type, member) + +/** + * list_first_entry - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note, that list is expected to be not empty. + */ +#define rmb_list_first_entry(ptr, type, member) \ + rmb_list_entry((ptr)->next, type, member) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define rmb_list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); \ + pos = pos->next) + +/** + * __list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + * + * This variant differs from list_for_each() in that it's the + * simplest possible list iteration code, no prefetching is done. + * Use this for code that knows the list to be very short (empty + * or 1 entry) most of the time. + */ +#define __rmb_list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define rmb_list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); \ + pos = pos->prev) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define rmb_list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry + * @pos: the &struct list_head to use as a loop cursor. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define rmb_list_for_each_prev_safe(pos, n, head) \ + for (pos = (head)->prev, n = pos->prev; \ + pos != (head); \ + pos = n, n = pos->prev) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define rmb_list_for_each_entry(pos, head, member) \ + for (pos = rmb_list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = rmb_list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_reverse - iterate backwards over list of given type. + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define rmb_list_for_each_entry_reverse(pos, head, member) \ + for (pos = rmb_list_entry((head)->prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = rmb_list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() + * @pos: the type * to use as a start point + * @head: the head of the list + * @member: the name of the list_struct within the struct. + * + * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). + */ +#define rmb_list_prepare_entry(pos, head, member) \ + ((pos) ? : rmb_list_entry(head, typeof(*pos), member)) + +/** + * list_for_each_entry_continue - continue iteration over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Continue to iterate over list of given type, continuing after + * the current position. + */ +#define rmb_list_for_each_entry_continue(pos, head, member) \ + for (pos = rmb_list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = rmb_list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_continue_reverse - iterate backwards from the given point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Start to iterate over list of given type backwards, continuing after + * the current position. + */ +#define rmb_list_for_each_entry_continue_reverse(pos, head, member) \ + for (pos = rmb_list_entry(pos->member.prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = rmb_list_entry(pos->member.prev, typeof(*pos), member)) + +/** + * list_for_each_entry_from - iterate over list of given type from the current point + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type, continuing from current position. + */ +#define rmb_list_for_each_entry_from(pos, head, member) \ + for (; &pos->member != (head); \ + pos = rmb_list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define rmb_list_for_each_entry_safe(pos, n, head, member) \ + for (pos = rmb_list_entry((head)->next, typeof(*pos), member), \ + n = rmb_list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = rmb_list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_continue + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type, continuing after current point, + * safe against removal of list entry. + */ +#define rmb_list_for_each_entry_safe_continue(pos, n, head, member) \ + for (pos = rmb_list_entry(pos->member.next, typeof(*pos), member), \ + n = rmb_list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = rmb_list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_from + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate over list of given type from current point, safe against + * removal of list entry. + */ +#define rmb_list_for_each_entry_safe_from(pos, n, head, member) \ + for (n = rmb_list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = rmb_list_entry(n->member.next, typeof(*n), member)) + +/** + * list_for_each_entry_safe_reverse + * @pos: the type * to use as a loop cursor. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Iterate backwards over list of given type, safe against removal + * of list entry. + */ +#define rmb_list_for_each_entry_safe_reverse(pos, n, head, member) \ + for (pos = rmb_list_entry((head)->prev, typeof(*pos), member), \ + n = rmb_list_entry(pos->member.prev, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = rmb_list_entry(n->member.prev, typeof(*n), member)) + +#endif /* RMB_LIST_H_ */ diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_log.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_log.h new file mode 100644 index 0000000000..5ebae8fcf8 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_log.h @@ -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. + +#ifndef _RMB_LOG_H_ +#define _RMB_LOG_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum RMB_LOG_TYPE +{ + RMB_LOG_TYPE_NORMAL = 0, //不需要滚动 + RMB_LOG_TYPE_CYCLE, //按大小滚动 + RMB_LOG_TYPE_DAILY, //按日期滚动 + RMB_LOG_TYPE_DAILY_AND_CYCLE, //按日期和大小一起滚动 + RMB_LOG_TYPE_CYCLE_BY = 6, //按大小滚动 +}; + +enum RMB_LOG_LEVEL +{ + RMB_LOG_FATAL = 0, + RMB_LOG_ERROR, + RMB_LOG_WARN, + RMB_LOG_INFO, + RMB_LOG_DEBUG, + RMB_LOG_ALL +}; + +typedef struct StRmbLogPara +{ + int _logLevel; + int _shiftType; + char _path[256]; + int _maxFileSize; + int _maxFileNum; +} StRmbLogPara; + +typedef struct StRmbLog +{ + FILE *_pStatFile; + FILE *_pLogFile; + char _logStatFileName[300]; + int _fd; + //int _fileOpen; //表示文件是否打开 + char _logFileName[300]; //next shift, 当前日志文件需要rename的名字 + char _logBaseFileName[280]; //当前写的日志名字 + time_t _lastShiftTime; + int _curFileNums; //当前日志数 + int _curFileNo; //当前第几个日志或者当天第几个日志,circle删除看这个 + + int _curFileSize; //当前日志大小 + + int _toDeleteFileNo; //for circle + char _toDeleteFileName[300]; //for daily + time_t _toDeleteTime; //删除哪天的日志 + StRmbLogPara _para; + + //pthread_spinlock_t logSpinLock = SPIN_LOCK_UNLOCKED; //自旋锁 + pthread_mutex_t rmbLogMutex; //临界区 + struct timeval stLogTv; + struct stat gRmbSb; + + //for file lock + struct flock logFileLock; + struct flock logStateLock; +} StRmbLog; + +typedef struct StDayInfo +{ + unsigned int _curFileNo; //当前天,下一个rename的名字 + unsigned int _deleteFileNo; //当前天,马上要被delete的序号 + time_t _dayTime; //代表当前天的时间 + unsigned int _curFileNum; //当前天的日志个数 + + char _baseFileName[280]; + char _logFileName[300]; +} StDayInfo; + +int ReloadCfg (int logLevel, int shiftType, const char *path, int maxFileSize, + int maxFileNum); +int GetCurFileNumFromStatFile (); +int SetCurFileNumToStatFile (); +int InitRmbLogFile (int logLevel, int shiftType, const char *path, + int maxFileSize, int maxFileNum); +int OpenRmbLog (); +int FindNextDeleteLog (); +int LogRmb (int logLevel, const char *format, ...); +int ShiftRmbLog (FILE * file); +int GetCurStateFromRmbLogByCirCle (); +int GetCurStateFromRmbLogByDaily (); +int GetCurStateFromRmbLogByDaily_V2 (); +int GetCurStateFromRmbLogByDaily_V3 (); +int GetCurStateFromRmbLogByDaily_V4 (); +int GetDayInfo (StDayInfo * dayInfo, time_t * curTime); +int GetDayInfoWithBreak (StDayInfo * dayInfo, time_t * curTime); +int GetRmbNowLongTime (); + +void _Log_Thread_func (void *args); +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_mq.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_mq.h new file mode 100644 index 0000000000..0aebc9532d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_mq.h @@ -0,0 +1,282 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RMB_MQ_H_ +#define RMB_MQ_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rmb_define.h" +#include "rmb_msg.h" +#include "rmb_sub.h" + +//typedef void (*rmb_callback_func)(const char*, const int, const int type, void*); +//typedef int(*rmb_callback_func_v2)(const char*, const int, void*); +//#define MAX_MQ_NUMS 10 +//#define MAX_FIFO_PATH_NAME_LEN 200 +//#define MAX_MQ_PKG_SIZE 10000000 +////static const unsigned int C_RMB_MQ_HEAD_SIZE = 2 * sizeof(unsigned int); +//#define C_RMB_MQ_HEAD_SIZE 2 * sizeof(unsigned int) +//#define C_RMB_MQ_PKG_HEAD_SIZE 2 * sizeof(unsigned int) +////static const unsigned int C_RMB_MQ_PKG_HEAD_SIZE = 2 * sizeof(unsigned int); + +//*************************for mq***************************** +//typedef struct StRmbMq +//{ +// unsigned int uiShmkey; +// unsigned long ulShmId; +// unsigned int uiShmSize; +// +// //head + tail + real data +// char* pMqData; +// unsigned int *pHead; +// unsigned int *pTail; +// +// //real data +// char *pBlock; +// unsigned int uiBlockSize; +// +//}StRmbMq; + +//mq init + int rmb_mq_init (StRmbMq * pMq, const unsigned int shmKey, + const unsigned int shmSize, const int bCreate, + const int bReadOnly); + +//mq_enqueue + int rmb_mq_enqueue (StRmbMq * pMq, const char *data, unsigned int uiDataLen, + unsigned int uiFLow); + +//mq_dequeue + int rmb_mq_dequeue (StRmbMq * pMq, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId); + +//mq_try_deuque + int rmb_mq_try_dequeue (StRmbMq * pMq, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId); + +//mq_get_stat + int rmb_mq_get_stat (StRmbMq * pMq); + +//*************************for fifo***************************** +//typedef struct StRmbFifo +//{ +// int iFd; +// char strPath[MAX_FIFO_PATH_NAME_LEN]; +//}StRmbFifo; + +//fifo init +//return -1 exist error + int rmb_fifo_init (StRmbFifo * pFifo, const char *pPath); + +//fifo + int rmb_fifo_send (StRmbFifo * pFifo); + +//clear notify + int rmb_fifo_clear_flag (StRmbFifo * pFifo); + +//*************************for queue****************************** +//typedef struct StRmbQueue +//{ +// unsigned int uiSize; +// +// //head + tail + real data +// char* pData; +// unsigned int *pHead; +// unsigned int *pTail; +// +// //real data +// char *pBlock; +// unsigned int uiBlockSize; +//}StRmbQueue; + +//queue init + int rmb_queue_init (StRmbQueue * pQue, const unsigned int size); + +//enqueue + int rmb_queue_enqueue (StRmbQueue * pQue, const char *data, + unsigned int uiDataLen, unsigned int uiFLow); + +//dequeue + int rmb_queue_dequeue (StRmbQueue * pQue, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId); + +//try deuque + int rmb_queue_try_dequeue (StRmbQueue * pQue, char *buf, + unsigned int uiBufSize, unsigned int *pDataLen, + unsigned int *pFlowId); + +//get stat + int rmb_queue_get_stat (StRmbQueue * pQue); + +//*************************for pipe***************************** +//typedef struct StRmbPipe +//{ +// int fd[2]; +// int r_fd; +// int w_fd; +//}StRmbPipe; + +//pipe init +//return -1 exist error + int rmb_pipe_init (StRmbPipe * pPipe); + +//pipe + int rmb_pipe_send (StRmbPipe * pPipe); + +//clear notify + int rmb_pipe_clear_flag (StRmbPipe * pPipe); + +//*************************for mq & notify*********************** +//typedef struct StMqInfo +//{ +// StRmbMq* mq; +// StRmbFifo* fifo; +// +// //for wemq +// StRmbQueue *que; +// StRmbPipe *pipe; +// +// int iIndex; //offset in vector +// int iMsgType; //iPkgType,1 queue msg;2 rr topic msg;3 broadcast msg;4 manage msg +// +// rmb_callback_func func; +// rmb_callback_func_v2 funcForNew; +// void* args; +// +// //for epoll +// int active; +// +// //for notify num +// int iCount; +// unsigned int uiLastCheckTime; +// +// int iMergeNotifyFLag; //0:not marge 1:marge +// int iNotifyFactor; //the factor of notify +//}StMqInfo; + +//enum RmbMqIndex +//{ +// req_mq_index = 1, +// rr_rsp_mq_index = 2, +// broadcast_mq_index = 3, +// manage_mq_index = 4, +// +// wemq_req_mq_index = 5, +// wemq_rr_rsp_mq_index = 6, +// wemq_broadcast_mq_index = 7, +// wemq_manage_mq_index = 8, +//}; +// +////for mq notify +//typedef struct StRmbMqFifoNotify +//{ +// StMqInfo vecMqInfo[MAX_MQ_NUMS]; +// int iMqNum; +// +// StMqInfo* mqIndex[MAX_MQ_NUMS]; //see define of RmbMqIndex +// //for select +// fd_set readFd; +// fd_set tmpReadFd; +// struct timeval tv; +// int iMaxFd; +// +// //for epoll +// int iEpollFd; +// +// char* pBuf; +// unsigned int uiBufLen; +// int type; +// +//}StRmbMqFifoNotify; + +//******************************************************function******************************s + + int rmb_notify_init (StRmbMqFifoNotify * pMqNotify); + +//notify add + int rmb_notify_add (StRmbMqFifoNotify * pMqNotify, StRmbMq * mq, + StRmbFifo * fifo, const enum RmbMqIndex iMsgType, + rmb_callback_func func, void *func_argv); + +//enqueue +//-1:error argv +//-2:not enough space +//-3:enquque error +//-4:notify send failed + int rmb_notify_enqueue_by_type (StRmbMqFifoNotify * pMqNotify, + const enum RmbMqIndex uiMsgType, + const unsigned int uiCurTime, + const char *data, unsigned int uiDataLen); + +//enqueue +//-1:error argv +//-2:not enough space +//-3:enquque error +//-4:notify send failed + int rmb_notify_enqueue (const unsigned int uiCurTime, StMqInfo * pMqInfo, + const char *data, unsigned int uiDataLen); + +//dequeue + int rmb_notify_dequeue (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen); + +//try dequeue + int rmb_notify_try_dequeue (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen); + +//**************select or epoll************************* +//select fifo fd +//return >0 the mq index which has msg +// =0 all mq has no msg +// <0 all mq has no msg +//int rmb_notify_select(StRmbMqFifoNotify* pMqNotify, unsigned int uiSec, unsigned int uiUsec); + +//epoll mq + int rmb_notify_epoll (StRmbSub * pStRmbSub, int iTimeout); + +//filter rmb msg + int rmb_epoll_msg_filter (StRmbSub * pStRmbSub, StRmbMsg * pReceiveMsg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_msg.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_msg.h new file mode 100644 index 0000000000..e606ed9fb5 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_msg.h @@ -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. + +#ifndef RMB_MSG_H_ +#define RMB_MSG_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rmb_define.h" + + int rmb_msg_clear (StRmbMsg * pStMsg); + int rmb_msg_init (StRmbMsg * pRmbMsg, StRmbConfig * pConfig, + enum RMB_API_YPE type); + +//set fields +//you must fill in under fields + int rmb_msg_set_bizSeqNo (StRmbMsg * pRmbMsg, const char *cBizSeqNo); + + int rmb_msg_set_consumerSysVersion (StRmbMsg * pRmbMsg, + const char *cConsumerSysVersion); + + int rmb_msg_set_consumerSeqNo (StRmbMsg * pRmbMsg, + const char *cConsumerSeqNo); + + int rmb_msg_set_orgSysId (StRmbMsg * pRmbMsg, const char *cOrgSysId); + +//dyed msg,optional + int rmb_msg_set_dyedMsg (StRmbMsg * pRmbMsg, const char *sign); + +/* +Function: rmb_msg_set_dest +Description:设置发送目标 +Retrun:见rmb_error.h +*/ + + int rmb_msg_set_dest (StRmbMsg * pRmbMsg, int desType, + const char *cTargetDcn, int iServiceOrEven, + const char *cServiceId, const char *cScenario); + + int rmb_msg_set_dest_v2 (StRmbMsg * pRmbMsg, const char *cTargetDcn, + const char *cServiceId, const char *cScenario); + +//指定法人 + int rmb_msg_set_dest_v2_1 (StRmbMsg * pRmbMsg, const char *cTargetDcn, + const char *cServiceId, const char *cScenario, + const char *cTargetOrgId); + + int rmb_msg_set_live_time (StRmbMsg * pRmbMsg, unsigned long ulLiveTime); + + int rmb_msg_set_app_header (StRmbMsg * pRmbMsg, const char *appHeader, + unsigned int uiLen); + + int rmb_msg_set_content (StRmbMsg * pRmbMsg, const char *content, + unsigned int uiLen); + + const char *rmb_msg_print (StRmbMsg * pRmbMsg); + int rmb_msg_print_v (StRmbMsg * pRmbMsg); + +//获取msg的消息类型 +/** +* get msg type +* 0: undefined type +* 1: request in queue +* 2: reply package in RR +* 3: broadcast +* see: C_RMB_PKG_TYPE +*/ + int rmb_msg_get_msg_type (StRmbMsg * pRmbMsg); +//get cUniqueId + const char *rmb_msg_get_uniqueId_ptr (StRmbMsg * pRmbMsg); +//get cBizSeqNo + const char *rmb_msg_get_biz_seq_no_ptr (StRmbMsg * pRmbMsg); +//get cConsumerSeqNo + const char *rmb_msg_get_consumer_seq_no_ptr (StRmbMsg * pRmbMsg); +//get cConsumerDcn + const char *rmb_msg_get_consumer_dcn_ptr (StRmbMsg * pRmbMsg); +//get cOrgSysId + const char *rmb_msg_get_org_sys_id_ptr (StRmbMsg * pRmbMsg); +//get cOrgId + const char *rmb_msg_get_org_id_ptr (StRmbMsg * pRmbMsg); + +//get dest.cDestName + int rmb_msg_get_dest (StRmbMsg * pRmbMsg, char *dest, unsigned int *uiLen); + const char *rmb_msg_get_dest_ptr (StRmbMsg * pRmbMsg); + +//get cConsumerSysId + int rmb_msg_get_consumerSysId (StRmbMsg * pRmbMsg, char *cConsumerSysId, + unsigned int *uiLen); + const char *rmb_msg_get_consumerSysId_ptr (StRmbMsg * pRmbMsg); + +//cConsumerSvrId + int rmb_msg_get_consumerSvrId (StRmbMsg * pRmbMsg, char *cConsumerSvrId, + unsigned int *uiLen); + const char *rmb_msg_get_consumerSvrId_ptr (StRmbMsg * pRmbMsg); + +//获取appHeader + int rmb_msg_get_app_header (StRmbMsg * pRmbMsg, char *userHeader, + unsigned int *pLen); + +//获取appHeader指针 + const char *rmb_msg_get_app_header_ptr (StRmbMsg * pRmbMsg, + unsigned int *pLen); + +//获取消息内容 + int rmb_msg_get_content (StRmbMsg * pRmbMsg, char *content, + unsigned int *pLen); + +//获取消息内容指针 + const char *rmb_msg_get_content_ptr (StRmbMsg * pRmbMsg, + unsigned int *pLen); + +//将2进制buf反序列化为rmbMsg + int shift_buf_2_msg (StRmbMsg * pStMsg, const char *cBuf, + unsigned int uiLen); + +//将rmbMsg序列化成2进制buf + int shift_msg_2_buf (char *cBuf, unsigned int *pLen, + const StRmbMsg * pStMsg); + +//rmbMsg各必填字段校验 + int rmb_check_msg_valid (StRmbMsg * pStMsg); + +//获取下一个合适的连接 + int rmb_get_fit_size (const unsigned int uiLen, + const unsigned int uiMaxLen); + +//消息初始化 + StRmbMsg *rmb_msg_malloc (); + +//消息释放 + int rmb_msg_free (StRmbMsg * pRmbMsg); + +//wemq json message to rmb msg + int trans_json_2_rmb_msg (StRmbMsg * pStMsg, const char *bodyJson, + const char *command); + +//set extfields something to rmb msg + int set_extfields_2_rmb_msg (StRmbMsg * pStMsg, const char *command, + int iSeq); + +//生成uuid + int rmb_msg_random_uuid (char *puuid, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_pub.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_pub.h new file mode 100644 index 0000000000..7dcb435841 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_pub.h @@ -0,0 +1,157 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * rmb_pub.h + * ---rmb的发包管理,包括发送广播、RR模式等 + * + * History: + * 2014-11-06 RR模式、发topic包 + */ +#ifndef RMB_PUB_H_ +#define RMB_PUB_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include "rmb_define.h" +#include "rmb_msg.h" +#include "message_log_api.h" + + typedef struct StRmbPub + { + StContext *pContext; + //StConfig config; + //for rr send msg + char cRrReplyTopic[200]; + int uiContextNum; //是否已经初始化 + + //for control send to wemq or solace + unsigned long ulLastTime; + unsigned int uiWeight; + + pthread_mutex_t pubMutex; //临界区 + StRmbMsg *pSendMsg; + StRmbMsg *pRcvMsg; + char pkgBuf[MAX_GSL_REQ_BUF_SIZE]; + char printGslBuf[1000]; + } StRmbPub; + +/** +Function: rmb_pub_init +Description:initialize +Retrun: + 0 --success + -1 --failed +*/ + int rmb_pub_init (StRmbPub * rmb_pub); + + int rmb_pub_init_python (); + +/** +Function: rmb_pub_send_and_receive +Description:send message and wait for report +Retrun: + 0 --success + -1 --timeout + -2 --error +*/ + int rmb_pub_send_and_receive (StRmbPub * rmb_pub, StRmbMsg * pSendMsg, + StRmbMsg * pRevMsg, unsigned int uiTimeOut); + int rmb_pub_send_and_receive_python (StRmbMsg * pSendMsg, + StRmbMsg * pRevMsg, + unsigned int uiTimeOut); + +/** +Function: rmb_pub_send_msg +Description:send message +Retrun: + 0 --success + -1 --failed + -2 --queue full +*/ + int rmb_pub_send_msg (StRmbPub * rmb_pub, StRmbMsg * pStMsg); + + int rmb_pub_send_msg_python (StRmbMsg * pStMsg); + +/** +Function: rmb_pub_send_rr_msg +Description:send RR asynchronous message +Retrun: + 0 --success + -1 --failed + -2 --queue full +*/ + int rmb_pub_send_rr_msg_async (StRmbPub * rmb_pub, StRmbMsg * pStMsg, + unsigned int uiTimeOut); + int rmb_pub_send_rr_msg_async_python (StRmbMsg * pStMsg, + unsigned int uiTimeOut); + +/** +Function: rmb_pub_reply_msg +Description:send report packet +Retrun: + 0 --success + -1 --failed +*/ + int rmb_pub_reply_msg (StRmbPub * pRmbPub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg); + +/** +Function: rmb_pub_close +Description:close pub +Retrun: + 0 --success + -1 --failed +*/ + int rmb_pub_close (StRmbPub * pRmbPub); + int rmb_pub_close_python (); + +/** +Function: rmb_pub_close_v2 +Description:close pub对象,2.0.12后使用 +Retrun: + 0 --success + -1 --failed +*/ + int rmb_pub_close_v2 (StRmbPub * pRmbPub); + + int rmb_pub_encode_thread_msg (unsigned int uiCmd, + StWemqThreadMsg * ptThreadMsg, + StRmbMsg * ptSendMsg, + unsigned long ulTimeToAlive); + +/** + * 给GSL发送染色消息 + */ + int rmb_pub_send_dyed_msg_to_gsl (StRmbPub * pStPub); + +//extern StRmbPub *pRmbGlobalPub; + +/* + * send log to logserver by wemq + * when iLogPoint is RMB_LOG_ON_ERROR, need iErrCode, cErrMsg + * others, not need + */ +//int rmb_send_log_to_logserver(StRmbMsg *pStMsg, int iContextType, int iLogPoint, int iErrCode, char* cErrMsg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_sub.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_sub.h new file mode 100644 index 0000000000..8ab677e3d8 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_sub.h @@ -0,0 +1,335 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RMB_SUB_H_ +#define RMB_SUB_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include "rmb_msg.h" +#include "rmb_context.h" +#include "rmb_define.h" +#include "rmb_udp.h" + + typedef struct StRmbSub + { + StContext *pStContext; + unsigned int uiContextNum; + //for rr reply topic + char cRrReply[255]; + unsigned int uiInitFlag; + //for filter unlisten receive msg + //unsigned int uiFlagForFilter; //rr异步与sub做区分 + //unsigned int uiFlagForSubType; + st_rmb_queue_info *pQueueInfo; + int iQueueNum; + //char **cTopic; + //int iTopicNum; + /* + //for rev req + int iReqPort; + + //for rev reply + int iReplyPort; + + //for rev broadcast + int iBroadcastPort; + */ + } StRmbSub; + +/** + * Function: rmb_sub_init + * Description: rmb sub对象初始化 + * Return: + * 见rmb_errno.h文件 + */ + int rmb_sub_init (StRmbSub * stRmbSub); + + int rmb_sub_init_python (); + +/** + * Function: rmb_sub_add_reveive_req + * Description: init, sub add receive queue request packet + * Return: + * 见rmb_errno.h文件 + */ +#define rmb_sub_add_reveive_req_by_udp rmb_sub_add_reveive_req + int rmb_sub_add_reveive_req (StRmbSub * stRmbSub, + unsigned short usRevReqPort); + +/* +* Function: rmb_sub_add_reveive_req_by_mq +* Description:初始化接收请求的操作(使用mq接收) +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_req_by_mq (StRmbSub * stRmbSub, + rmb_callback_func func, void *func_argv); + +/* +* Function: rmb_sub_add_reveive_req_by_mq_v2 +* Description:初始化接收请求的操作(使用mq接收),自定义mq的key +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_req_by_mq_v2 (StRmbSub * stRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + + int rmb_sub_add_reveive_req_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + +/* +Function: rmb_sub_get_receve_req_mq +Description:获取接收请求的mq对象 +* Return: +* 见rmb_errno.h文件 +*/ + StMqInfo *rmb_sub_get_receve_req_mq (StRmbSub * stRmbSub); + +/* +Function: rmb_sub_add_reveive_rsp +Description:初始化接收回包(使用UDP) +* Return: +* 见rmb_errno.h文件 +*/ +#define rmb_sub_add_reveive_rsp_by_udp rmb_sub_add_reveive_rsp + int rmb_sub_add_reveive_rsp (StRmbSub * stRmbSub, + unsigned short usRevRspPort); + +/* +Function: rmb_sub_add_reveive_rsp_by_mq +Description:初始化接收回包(使用mq) +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_rsp_by_mq (StRmbSub * stRmbSub, + rmb_callback_func func, void *func_argv); + +/* +Function: rmb_sub_add_reveive_rsp_by_mq_v2 +Description:初始化接收回包(使用UDP),自定义mq key +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_rsp_by_mq_v2 (StRmbSub * stRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + + int rmb_sub_add_reveive_rsp_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + +/* +Function: rmb_sub_get_receve_rsp_mq +Description:获取接收回包的mq对象 +* Return: +* 见rmb_errno.h文件 +*/ + StMqInfo *rmb_sub_get_receve_rsp_mq (StRmbSub * stRmbSub); + +/* +Function: rmb_sub_add_reveive_broadcast +Description:初始化接收广播(使用UDP) +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_broadcast (StRmbSub * stRmbSub, + unsigned short usRevBroadcastPort); + +/* +Function: rmb_sub_add_reveive_broadcast_by_mq +Description:初始化接收广播(使用mq) +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_broadcast_by_mq (StRmbSub * stRmbSub, + rmb_callback_func func, + void *func_argv); + +/* +Function: rmb_sub_add_reveive_broadcast_by_mq_v2 +Description:初始化接收回包(使用mq),自定义mq key +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_add_reveive_broadcast_by_mq_v2 (StRmbSub * stRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv); + int rmb_sub_add_reveive_broadcast_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int + uiShmSize, + rmb_callback_func func, + void *func_argv); + +/* +Function: rmb_sub_get_receve_broadcast_mq +Description:获取接收回包mq对象 +* Return: +* 见rmb_errno.h文件 +*/ + StMqInfo *rmb_sub_get_receve_broadcast_mq (StRmbSub * stRmbSub); + +/* +Function: rmb_sub_get_fd +Description:获取mq对象的fd +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_get_fd (StMqInfo * pMqInfo); + +/* +Function: rmb_sub_receive_from_mq +Description:从mq中获取消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_receive_from_mq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen); + +/* +Function: rmb_sub_try_receive_from_mq +Description:尝试从mq中获取消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_try_receive_from_mq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen); + +/* +Function: rmb_sub_add_listen +Description:听queue +* Return: +* 见rmb_errno.h文件 +*/ +//int rmb_sub_add_listen(StRmbSub *pStRmbSub, const char *cOwnDcn, int iServiceOrEven, const char *cServiceId, const char *cScenario); + int rmb_sub_add_listen (StRmbSub * pStRmbSub, + const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize); + + int rmb_sub_add_listen_python (const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize); + +/* +Function: rmb_sub_add_listen_broadcast +Description:听topic +* Return: +* 见rmb_errno.h文件 +*/ +//int rmb_sub_add_listen_broadcast(StRmbSub *pStRmbSub, const char *cOwnDcn, const char *cServiceId, const char *cScenario); + +/* +Function: rmb_sub_do_receive +Description:听queue +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_do_receive (StRmbSub * pStRmbSub, int iTimeout); + + int rmb_sub_do_receive_python (); + +/* +Function: rmb_sub_reply_msg +Description:回复消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_reply_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg); + + int rmb_sub_reply_msg_python (StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg); + +/* +Function: rmb_sub_ack_msg +Description:ack消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_ack_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg); + +/* +Function: rmb_sub_close +Description:关闭rmb_sub对象 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_close (StRmbSub * pStRmbSub); + int rmb_sub_close_python (); + +/* +Function: rmb_sub_close_v2 +Description:关闭rmb_sub对象,2.0.12后使用 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_close_v2 (StRmbSub * pStRmbSub); + +/* +Function: rmb_sub_stop_receive +Description:rmb_sub停止接受queue消息 +* Return: +* 见rmb_errno.h文件 +*/ + int rmb_sub_stop_receive (StRmbSub * pStRmbSub); + int rmb_sub_stop_receive_python (); + +/* +Function: rmb_sub_check_req_mq_is_null +Description:校验是否请求队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ + int rmb_sub_check_req_mq_is_null (StRmbSub * pStRmbSub); + + unsigned long rmb_get_topic_thread_id (); + +/** + * 专用于监听wemq的旁路topic + */ +//int rmb_sub_add_listen_topic_bypass(StRmbSub *pStRmbSub, const char *cTopic); + int rmb_sub_add_listen_topic_bypass (StRmbSub * pStRmbSub, + const char **cTopic, + unsigned int uiTopicSize); + + unsigned long rmb_get_topic_thread_id (); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_udp.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_udp.h new file mode 100644 index 0000000000..7dc9e7180c --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_udp.h @@ -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. + +#ifndef _UDP_SOCKET_FOR_RMB_H_ +#define _UDP_SOCKET_FOR_RMB_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include /* required for ip.h */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//////////////////////// +#include "rmb_define.h" +//////////////////////// + + typedef struct sockaddr_in StSockAddr; + + int udp_get_socket (const char *host, const char *serv, + socklen_t * addrlenp); + + int udp_server (const char *pszHost, unsigned short usPort); + + int check_socket (int iSocket, fd_set * stReadFds, int iNFd); + + int check_socket_with_timeout (int iSocket, fd_set * pStReadFds, int iNfd, + int sec, int usec); + + int check_and_process_socket (int iSocket, fd_set * stReadFds, + char *cPkgBuf, const unsigned int uiMaxLen, + unsigned int *pPkgLen); + + int tcp_nodelay (int iSockfd); + + int get_host_name (char *hostName, unsigned int uiHostNameLen); + + int get_local_ip (char *addr, unsigned int uiAddrLen); + + int get_local_ip_v2 (char *addr, unsigned int uiAddrLen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/rmb_vector.h b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_vector.h new file mode 100644 index 0000000000..31055477ae --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/rmb_vector.h @@ -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. + +#ifndef __RMB_VECTOR_H_ +#define __RMB_VECTOR_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include +#include "rmb_define.h" + +#define MAX_SIZE_PER_TIME 1024 + + void Init (Array * this); + void _constructor (Array * this); + void _destructor (Array * this); + void _input (DataType data, Array * this); + int _get_size (Array * this); + DataType _return_index_value (Array * this, int index); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_fifo.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_fifo.h new file mode 100644 index 0000000000..eed6129af9 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_fifo.h @@ -0,0 +1,639 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + * API : + * DEFINE_WEMQ_KFIFO : statically allocated FIFO object + * DECLARE_WEMQ_KFIFO : declare a FIFO object + * DECLARE_WEMQ_KFIFO_PTR: declare a pointer whitch point to a FIFO object + * INIT_WEMQFIFO : init a FIFO object + * + * wemq_kfifo_len : return the num of element that in the fifo + * wemq_kfifo_peek_len: return the num of bytes that in use + * + * wemq_kfifo_is_empty: retruns true if the fifo is empty + * wemq_kfifo_is_full : returns true if the fifo is full + * wemq_kfifo_is_avail: returns the numer of unused elements in the fifo + * wemq_kfifo_skip : skip a element in fifo + * + * wemq_kfifo_alloc : dynamically allocates a new fifo buffer + * wemq_kfifo_free : frees the fifo + * + * wemq_kfifo_put : copies the given value into the fifo (by element) + * wemq_kfifo_get : reads a element from the fifo + * wemq_kfifo_peek : reads a element from the fifo without removing it form the fifo + * + * wemq_kfifo_in : copies the given buffer into the fifo and returnns the number of copied elements + * wemq_kfifo_out : get some elements form the fifo and return the numbers of elements + * wemq_kfifo_out_peek: get the data from the fifo and return the numbers of elements copied. These elements is not removed from the fifo + * + */ + +#ifndef _WEMQ_WEMQ_KFIFO_H +#define _WEMQ_WEMQ_KFIFO_H +#ifdef __cplusplus +extern "C" +{ +#endif +//#include +//#include +//#include + +#define __u32 uint32_t +#define __u64 uint64_t +#define __must_check __attribute__((warn_unused_result)) + +#define __must_be_array(arr) 0 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) + + enum + { + KFIFO_EINVAL = -1, + KFIFO_ENOMEM = -2 + }; + + static inline int fls (int x) + { + int r; + + __asm__ ("bsrl %1,%0\n\t" + "jnz 1f\n\t" "movl $-1,%0\n" "1:":"=r" (r):"rm" (x)); + return r + 1; + } + + static inline int fls64 (__u64 x) + { + __u32 h = x >> 32; + if (h) + return fls (h) + 32; + return fls (x); + } + + static inline unsigned fls_long (unsigned long l) + { + if (sizeof (l) == 4) + return fls (l); + return fls64 (l); + } + + static inline unsigned long roundup_pow_of_two (unsigned long x) + { + return 1UL << fls_long (x - 1); + } + + struct __wemq_kfifo + { + unsigned int in; + unsigned int out; + unsigned int mask; + unsigned int esize; + void *data; + }; + +#define __STRUCT_WEMQ_KFIFO_COMMON(datatype, recsize, ptrtype) \ + union { \ + struct __wemq_kfifo wemq_kfifo; \ + datatype *type; \ + const datatype *const_type; \ + char (*rectype)[recsize]; \ + ptrtype *ptr; \ + ptrtype const *ptr_const; \ + } + +#define __STRUCT_WEMQ_KFIFO(type, size, recsize, ptrtype) \ +{ \ + __STRUCT_WEMQ_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ +} + +#define STRUCT_WEMQ_KFIFO(type, size) \ + struct __STRUCT_WEMQ_KFIFO(type, size, 0, type) + +#define __STRUCT_WEMQ_KFIFO_PTR(type, recsize, ptrtype) \ +{ \ + __STRUCT_WEMQ_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[0]; \ +} + +#define STRUCT_WEMQ_KFIFO_PTR(type) \ + struct __STRUCT_WEMQ_KFIFO_PTR(type, 0, type) + +/* + * define compatibility "struct wemq_kfifo" for dynamic allocated fifos + */ + struct st_wemq_kfifo __STRUCT_WEMQ_KFIFO_PTR (unsigned char, 0, void); + +#define STRUCT_WEMQ_KFIFO_REC_1(size) \ + struct __STRUCT_WEMQ_KFIFO(unsigned char, size, 1, void) + +#define STRUCT_WEMQ_KFIFO_REC_2(size) \ + struct __STRUCT_WEMQ_KFIFO(unsigned char, size, 2, void) + +/* + * define wemq_kfifo_rec types + */ + struct wemq_kfifo_rec_ptr_1 __STRUCT_WEMQ_KFIFO_PTR (unsigned char, 1, + void); + struct wemq_kfifo_rec_ptr_2 __STRUCT_WEMQ_KFIFO_PTR (unsigned char, 2, + void); + +/* + * helper macro to distinguish between real in place fifo where the fifo + * array is a part of the structure and the fifo type where the array is + * outside of the fifo structure. + */ +#define __is_wemq_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __wemq_kfifo)) + +/** + * DECLARE_WEMQ_KFIFO_PTR - macro to declare a fifo pointer object + * @fifo: name of the declared fifo + * @type: type of the fifo elements + */ +#define DECLARE_WEMQ_KFIFO_PTR(fifo, type) STRUCT_WEMQ_KFIFO_PTR(type) fifo + +/** + * DECLARE_WEMQ_KFIFO - macro to declare a fifo object + * @fifo: name of the declared fifo + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 + */ +#define DECLARE_WEMQ_KFIFO(fifo, type, size) STRUCT_WEMQ_KFIFO(type, size) fifo + +/** + * INIT_WEMQ_KFIFO - Initialize a fifo declared by DECLARE_WEMQ_KFIFO + * @fifo: name of the declared fifo datatype + */ +#define INIT_WEMQ_KFIFO(fifo) \ +(void)({ \ + typeof(&(fifo)) __tmp = &(fifo); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + __wemq_kfifo->in = 0; \ + __wemq_kfifo->out = 0; \ + __wemq_kfifo->mask = __is_wemq_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ + __wemq_kfifo->esize = sizeof(*__tmp->buf); \ + __wemq_kfifo->data = __is_wemq_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ +}) + +/** + * DEFINE_WEMQ_KFIFO - macro to define and initialize a fifo + * @fifo: name of the declared fifo datatype + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 + * + * Note: the macro can be used for global and local fifo data type variables. + */ +#define DEFINE_WEMQ_KFIFO(fifo, type, size) \ + DECLARE_WEMQ_KFIFO(fifo, type, size) = \ + (typeof(fifo)) { \ + { \ + { \ + .in = 0, \ + .out = 0, \ + .mask = __is_wemq_kfifo_ptr(&(fifo)) ? \ + 0 : \ + ARRAY_SIZE((fifo).buf) - 1, \ + .esize = sizeof(*(fifo).buf), \ + .data = __is_wemq_kfifo_ptr(&(fifo)) ? \ + NULL : \ + (fifo).buf, \ + } \ + } \ + } + + static inline unsigned int __must_check + __wemq_kfifo_uint_must_check_helper (unsigned int val) + { + return val; + } + + static inline int __must_check __wemq_kfifo_int_must_check_helper (int val) + { + return val; + } + +/** + * wemq_kfifo_initialized - Check if the fifo is initialized + * @fifo: address of the fifo to check + * + * Return %true if fifo is initialized, otherwise %false. + * Assumes the fifo was 0 before. + */ +#define wemq_kfifo_initialized(fifo) ((fifo)->wemq_kfifo.mask) + +/** + * wemq_kfifo_esize - returns the size of the element managed by the fifo + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_esize(fifo) ((fifo)->wemq_kfifo.esize) + +/** + * wemq_kfifo_recsize - returns the size of the record length field + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) + +/** + * wemq_kfifo_size - returns the size of the fifo in elements + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_size(fifo) ((fifo)->wemq_kfifo.mask + 1) + +/** + * wemq_kfifo_reset - removes the entire fifo content + * @fifo: address of the fifo to be used + * + * Note: usage of wemq_kfifo_reset() is dangerous. It should be only called when the + * fifo is exclusived locked or when it is secured that no other thread is + * accessing the fifo. + */ +#define wemq_kfifo_reset(fifo) \ +(void)({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + __tmp->wemq_kfifo.in = __tmp->wemq_kfifo.out = 0; \ +}) + +/** + * wemq_kfifo_reset_out - skip fifo content + * @fifo: address of the fifo to be used + * + * Note: The usage of wemq_kfifo_reset_out() is safe until it will be only called + * from the reader thread and there is only one concurrent reader. Otherwise + * it is dangerous and must be handled in the same way as wemq_kfifo_reset(). + */ +#define wemq_kfifo_reset_out(fifo) \ +(void)({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + __tmp->wemq_kfifo.out = __tmp->wemq_kfifo.in; \ +}) + +/** + * wemq_kfifo_len - returns the number of used elements in the fifo + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_len(fifo) \ +({ \ + typeof((fifo) + 1) __tmpl = (fifo); \ + __tmpl->wemq_kfifo.in - __tmpl->wemq_kfifo.out; \ +}) + +/** + * wemq_kfifo_is_empty - returns true if the fifo is empty + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_is_empty(fifo) \ +({ \ + typeof((fifo) + 1) __tmpq = (fifo); \ + __tmpq->wemq_kfifo.in == __tmpq->wemq_kfifo.out; \ +}) + +/** + * wemq_kfifo_is_full - returns true if the fifo is full + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_is_full(fifo) \ +({ \ + typeof((fifo) + 1) __tmpq = (fifo); \ + wemq_kfifo_len(__tmpq) > __tmpq->wemq_kfifo.mask; \ +}) + +/** + * wemq_kfifo_avail - returns the number of unused elements in the fifo + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_avail(fifo) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmpq = (fifo); \ + const size_t __recsize = sizeof(*__tmpq->rectype); \ + unsigned int __avail = wemq_kfifo_size(__tmpq) - wemq_kfifo_len(__tmpq); \ + (__recsize) ? ((__avail <= __recsize) ? 0 : \ + __wemq_kfifo_max_r(__avail - __recsize, __recsize)) : \ + __avail; \ +}) \ +) + +/** + * wemq_kfifo_skip - skip output data + * @fifo: address of the fifo to be used + */ +#define wemq_kfifo_skip(fifo) \ +(void)({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__recsize) \ + __wemq_kfifo_skip_r(__wemq_kfifo, __recsize); \ + else \ + __wemq_kfifo->out++; \ +}) + +/** + * wemq_kfifo_peek_len - gets the size of the next fifo record + * @fifo: address of the fifo to be used + * + * This function returns the size of the next fifo record in number of bytes. + */ +#define wemq_kfifo_peek_len(fifo) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + (!__recsize) ? wemq_kfifo_len(__tmp) * sizeof(*__tmp->type) : \ + __wemq_kfifo_len_r(__wemq_kfifo, __recsize); \ +}) \ +) + +/** + * wemq_kfifo_alloc - dynamically allocates a new fifo buffer + * @fifo: pointer to the fifo + * @size: the number of elements in the fifo, this must be a power of 2 + * @gfp_mask: get_free_pages mask, passed to kmalloc() + * + * This macro dynamically allocates a new fifo buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * The fifo will be release with wemq_kfifo_free(). + * Return 0 if no error, otherwise an error code. + */ +#define wemq_kfifo_alloc(fifo, size) \ +__wemq_kfifo_int_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + __is_wemq_kfifo_ptr(__tmp) ? \ + __wemq_kfifo_alloc(__wemq_kfifo, size, sizeof(*__tmp->type)) : \ + -KFIFO_EINVAL; \ +}) \ +) + +/** + * wemq_kfifo_free - frees the fifo + * @fifo: the fifo to be freed + */ +#define wemq_kfifo_free(fifo) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__is_wemq_kfifo_ptr(__tmp)) \ + __wemq_kfifo_free(__wemq_kfifo); \ +}) + +/** + * wemq_kfifo_init - initialize a fifo using a preallocated buffer + * @fifo: the fifo to assign the buffer + * @buffer: the preallocated buffer to be used + * @size: the size of the internal buffer, this have to be a power of 2 + * + * This macro initialize a fifo using a preallocated buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * Return 0 if no error, otherwise an error code. + */ +#define wemq_kfifo_init(fifo, buffer, size) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + __is_wemq_kfifo_ptr(__tmp) ? \ + __wemq_kfifo_init(__wemq_kfifo, buffer, size, sizeof(*__tmp->type)) : \ + -KFIFO_EINVAL; \ +}) + +/** + * wemq_kfifo_put - put data into the fifo + * @fifo: address of the fifo to be used + * @val: the data to be added + * + * This macro copies the given value into the fifo. + * It returns 0 if the fifo was full. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_put(fifo, val) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(*__tmp->const_type) __val = (val); \ + unsigned int __ret; \ + size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__recsize) \ + __ret = __wemq_kfifo_in_r(__wemq_kfifo, &__val, sizeof(__val), \ + __recsize); \ + else { \ + __ret = !wemq_kfifo_is_full(__tmp); \ + if (__ret) { \ + (__is_wemq_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__wemq_kfifo->data) : \ + (__tmp->buf) \ + )[__wemq_kfifo->in & __tmp->wemq_kfifo.mask] = \ + *(typeof(__tmp->type))&__val; \ + __wemq_kfifo->in++; \ + } \ + } \ + __ret; \ +}) + +/** + * wemq_kfifo_get - get data from the fifo + * @fifo: address of the fifo to be used + * @val: address where to store the data + * + * This macro reads the data from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_get(fifo, val) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__recsize) \ + __ret = __wemq_kfifo_out_r(__wemq_kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !wemq_kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_wemq_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__wemq_kfifo->data) : \ + (__tmp->buf) \ + )[__wemq_kfifo->out & __tmp->wemq_kfifo.mask]; \ + __wemq_kfifo->out++; \ + } \ + } \ + __ret; \ +}) \ +) + +/** + * wemq_kfifo_peek - get data from the fifo without removing + * @fifo: address of the fifo to be used + * @val: address where to store the data + * + * This reads the data from the fifo without removing it from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_peek(fifo, val) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr) __val = (val); \ + unsigned int __ret; \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + if (__recsize) \ + __ret = __wemq_kfifo_out_peek_r(__wemq_kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !wemq_kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_wemq_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__wemq_kfifo->data) : \ + (__tmp->buf) \ + )[__wemq_kfifo->out & __tmp->wemq_kfifo.mask]; \ + } \ + } \ + __ret; \ +}) \ +) + +/** + * wemq_kfifo_in - put data into the fifo + * @fifo: address of the fifo to be used + * @buf: the data to be added + * @n: number of elements to be added + * + * This macro copies the given buffer into the fifo and returns the + * number of copied elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_in(fifo, buf, n) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr_const) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + (__recsize) ?\ + __wemq_kfifo_in_r(__wemq_kfifo, __buf, __n, __recsize) : \ + __wemq_kfifo_in(__wemq_kfifo, __buf, __n); \ +}) + +/** + * wemq_kfifo_out - get data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * + * This macro get some data from the fifo and return the numbers of elements + * copied. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_out(fifo, buf, n) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + (__recsize) ?\ + __wemq_kfifo_out_r(__wemq_kfifo, __buf, __n, __recsize) : \ + __wemq_kfifo_out(__wemq_kfifo, __buf, __n); \ +}) \ +) + +/** + * wemq_kfifo_out_peek - gets some data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * + * This macro get the data from the fifo and return the numbers of elements + * copied. The data is not removed from the fifo. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define wemq_kfifo_out_peek(fifo, buf, n) \ +__wemq_kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof(__tmp->ptr) __buf = (buf); \ + unsigned long __n = (n); \ + const size_t __recsize = sizeof(*__tmp->rectype); \ + struct __wemq_kfifo *__wemq_kfifo = &__tmp->wemq_kfifo; \ + (__recsize) ? \ + __wemq_kfifo_out_peek_r(__wemq_kfifo, __buf, __n, __recsize) : \ + __wemq_kfifo_out_peek(__wemq_kfifo, __buf, __n); \ +}) \ +) + + extern int __wemq_kfifo_alloc (struct __wemq_kfifo *fifo, unsigned int size, + size_t esize); + + extern void __wemq_kfifo_free (struct __wemq_kfifo *fifo); + + extern int __wemq_kfifo_init (struct __wemq_kfifo *fifo, void *buffer, + unsigned int size, size_t esize); + + extern unsigned int __wemq_kfifo_in (struct __wemq_kfifo *fifo, + const void *buf, unsigned int len); + + extern unsigned int __wemq_kfifo_out (struct __wemq_kfifo *fifo, + void *buf, unsigned int len); + + extern unsigned int __wemq_kfifo_out_peek (struct __wemq_kfifo *fifo, + void *buf, unsigned int len); + + extern unsigned int __wemq_kfifo_in_r (struct __wemq_kfifo *fifo, + const void *buf, unsigned int len, + size_t recsize); + + extern unsigned int __wemq_kfifo_out_r (struct __wemq_kfifo *fifo, + void *buf, unsigned int len, + size_t recsize); + + extern unsigned int __wemq_kfifo_len_r (struct __wemq_kfifo *fifo, + size_t recsize); + + extern void __wemq_kfifo_skip_r (struct __wemq_kfifo *fifo, size_t recsize); + + extern unsigned int __wemq_kfifo_out_peek_r (struct __wemq_kfifo *fifo, + void *buf, unsigned int len, + size_t recsize); + + extern unsigned int __wemq_kfifo_max_r (unsigned int len, size_t recsize); +#ifdef __cplusplus +} +#endif +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_proto.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_proto.h new file mode 100644 index 0000000000..1091be72a0 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_proto.h @@ -0,0 +1,562 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//wemq-c-api与access协议 +#ifndef _WEMQ_PROXY_WORKER_PROTO_H_ +#define _WEMQ_PROXY_WORKER_PROTO_H_ + +#include +#include +#include +#include + +//#pragma pack(1) +#ifdef __cplusplus +extern "C" +{ +#endif + +#define SERVICE_ID_LENGTH 9 +#define SCENE_ID_LENGTH 3 +#define MAX_LISTEN_SIZE 100 + +#define BYTES_LENGTH ((2<<8)-1) +#define WORD_LENGTH ((2<<16)-1) +#define DWORD_LENGTH ((2<<32)-1) + +#define MAX_MSG_WEMQ_MSG_SIZE 2200000 + +/** + * wemq建立监听topic时,在2.0.8版本之前的流程为: + * 第一阶段 发送hello world, access会建立CLIENT Hello session, new出producer和consumer,耗时大约4s + * 第二阶段发送订阅命令,access的subscribe会同时start和consumer,后续的第二次subscribe会有大量的topic not exist,命令如下: + * --- subscribe(51, "订阅(不区分同步/异步) topic") --- + * --- unsubscribe(50, "取消注册服务 --- topic") --- + * --- subscribeTopic(53, "订阅服务(不区分同步/异步) -- 针对非类似生产的topic,例如ft-bq-bypass") --- + * --- unsubscribeTopic(52, "取消注册服务 -- 针对非类似生产的topic, 例如ft-bq-bypass") --- + * + * 在2.0.8版本为了解决access使用wemq的sub和start时序问题,修改为如下: + * 第一阶段 发送hello world, access会建立CLIENT Hello session, new出producer和consumer,耗时大约1s + * 第二阶段只subscribe, 如果客户端有多个topic,则循环发出sub命令, access收到,会sub在第一阶段建立的consumer上,耗时大约30ms + * 第三阶段api发送start命令给access, access会Listen,将ready好的带上了subscribe信息的consumer启动起来,正式开始收发消息, 耗时大约是3s + * 命令字如下: + * --- subscribe(61, "订阅(不区分同步/异步) topic") --- + * --- unsubscribe(60, "取消注册服务 --- topic") --- + * --- subscribeTopic(63, "订阅服务(不区分同步/异步) -- 针对非类似生产的topic,例如ft-bq-bypass") --- + * --- unsubscribeTopic(62, "取消注册服务 -- 针对非类似生产的topic, 例如ft-bq-bypass") --- + * start命令字: + * listen request: + * decode|length=295|headerLength=291|bodyLength=0|header={"type":123,"time":1497331206231,"seq":8995349179,"status":0,"idc":"ft","ip":"10.39.84.50"}|body=null. + * listen response: + * encode|length=299|headerLength=291|bodyLength=0|header={"type":123,"time":1497331206231,"seq":8995349179,,"status":0,"idc":"ft","ip":"10.39.84.50"}|body=null. + * + * 在2.0.12版本,采用新的wemq-access协议 http://rpddoc.weoa.com/index.php?s=/389&page_id=3967 + +enum CMD_FOR_WEMQ_PROXY_WORKER +{ + //proxy offer + //client(worker)-->server(proxy) + WEMQ_CMD_HELLO = 0, //客户端上线通知 + WEMQ_CMD_GOODBYE = 88, //客户端离线通知 + WEMQ_CMD_CLIENTGOODBYE = 881, //客户端主动离线通知 + WEMQ_CMD_SERVERGOODBYE = 882, //access端主动离线通知 + WEMQ_CMD_HEARTBEAT = 66, //ECHO心跳包 + WEMQ_CMD_SYNCREQ = 10, //同步请求消息 + WEMQ_CMD_SYNCRSP = 11, //同步响应消息 + WEMQ_CMD_ASYNCRSP = 21, //RR异步响应消息 + WEMQ_CMD_ASYNCREQ = 20, //RR异步请求消息 + WEMQ_CMD_ASYNCEVENT_PUB = 30, //发送事件消息(发送端) + WEMQ_CMD_ASYNCEVENT_SUB = 31, //接收事件(订阅端) + WEMQ_CMD_ASYNCEVENT_LOG_PUB = 34, //发送事件(发送logserver的命令字) + WEMQ_CMD_BROADCAST_PUB = 40, //广播消息发送(发送端) + WEMQ_CMD_BROADCAST_SUB = 41, //广播消息接收(订阅端) + WEMQ_CMD_REDIRECT = 32, //重定向C客户端到新的ACCESS服务器 + WEMQ_CMD_SUB = 51, //订阅服务(不区分同步/异步) + WEMQ_UNSUBSCRIBE = 50, //取消注册服务 + WEMQ_ACKNOWLEDGED = 100, //ack消息 + WEMQ_UNACKNOWLEDGED = 59, //unack消息 + //由于wemq针对旁边的topic是没有dcn、服务ID等的概念,故增加如下SUB指令 + WEMQ_CMD_SUB_TOPIC = 53, //订阅topic + WEMQ_CMD_UNSUB_TOPIC = 52, //取消topic订阅 + //version 2.0.8 add, for access + WEMQ_CMD_SUB_LISTEN = 61, //订阅服务(不区分同步/异步) + WEMQ_UNSUBSCRIBE_LISTEN = 60, //取消注册服务 + //由于wemq针对旁边的topic是没有dcn、服务ID等的概念,故增加如下SUB指令 + WEMQ_CMD_SUB_TOPIC_LISTEN = 63, //订阅topic + WEMQ_CMD_UNSUB_TOPIC_LISTEN = 62, //取消topic订阅 + WEMQ_CMD_SUB_START = 123, //sub add listen之后,发送start命令 +}; +*/ + + //心跳 +#define HEARTBEAT_REQUEST "HEARTBEAT_REQUEST" //client发给server的心跳包 +#define HEARTBEAT_RESPONSE "HEARTBEAT_RESPONSE" //server回复client的心跳包 + //握手 +#define HELLO_REQUEST "HELLO_REQUEST" //client发给server的握手请求 +#define HELLO_RESPONSE "HELLO_RESPONSE" //server回复client的握手请求 + //断连 +#define CLIENT_GOODBYE_REQUEST "CLIENT_GOODBYE_REQUEST" //client主动断连时通知server +#define CLIENT_GOODBYE_RESPONSE "CLIENT_GOODBYE_RESPONSE" //server回复client的主动断连通知 +#define SERVER_GOODBYE_REQUEST "SERVER_GOODBYE_REQUEST" //server主动断连时通知client +#define SERVER_GOODBYE_RESPONSE "SERVER_GOODBYE_RESPONSE" //client回复server的主动断连通知(client不会回复,准备好之后直接断连) + //订阅管理 +#define SUBSCRIBE_REQUEST "SUBSCRIBE_REQUEST" //client发给server的订阅请求 +#define SUBSCRIBE_RESPONSE "SUBSCRIBE_RESPONSE" //server回复client的订阅请求 +#define UNSUBSCRIBE_REQUEST "UNSUBSCRIBE_REQUEST" //client发给server的取消订阅请求 +#define UNSUBSCRIBE_RESPONSE "UNSUBSCRIBE_RESPONSE" //server回复client的取消订阅请求 + //监听 +#define LISTEN_REQUEST "LISTEN_REQUEST" //client发给server的启动topic监听的请求 +#define LISTEN_RESPONSE "LISTEN_RESPONSE" //server回复client的监听请求 + +#define REQUEST_TO_SERVER "REQUEST_TO_SERVER" //client将RR请求发送给server +#define REQUEST_TO_CLIENT "REQUEST_TO_CLIENT" //server将RR请求推送给client +#define REQUEST_TO_CLIENT_ACK "REQUEST_TO_CLIENT_ACK" //client收到RR请求后回ack给server +#define RESPONSE_TO_SERVER "RESPONSE_TO_SERVER" //client将RR回包发送给server +#define RESPONSE_TO_CLIENT "RESPONSE_TO_CLIENT" //server将RR回包推送给client +#define RESPONSE_TO_CLIENT_ACK "RESPONSE_TO_CLIENT_ACK" //client收到RR回包后回ack给server + + //异步事件 +#define ASYNC_MESSAGE_TO_SERVER "ASYNC_MESSAGE_TO_SERVER" //client将异步事件发送给server +#define ASYNC_MESSAGE_TO_SERVER_ACK "ASYNC_MESSAGE_TO_SERVER_ACK" //server收到异步事件后ACK给client +#define ASYNC_MESSAGE_TO_CLIENT "ASYNC_MESSAGE_TO_CLIENT" //server将异步事件推送给client +#define ASYNC_MESSAGE_TO_CLIENT_ACK "ASYNC_MESSAGE_TO_CLIENT_ACK" // client收到异步事件后回ack给server + + //广播 +#define BROADCAST_MESSAGE_TO_SERVER "BROADCAST_MESSAGE_TO_SERVER" //client将广播消息发送给server +#define BROADCAST_MESSAGE_TO_SERVER_ACK "BROADCAST_MESSAGE_TO_SERVER_ACK" //server收到广播消息后ACK给client +#define BROADCAST_MESSAGE_TO_CLIENT "BROADCAST_MESSAGE_TO_CLIENT" //server将广播消息推送给client +#define BROADCAST_MESSAGE_TO_CLIENT_ACK "BROADCAST_MESSAGE_TO_CLIENT_ACK" //client收到异步事件后回ack给server + //日志上报 +#define TRACE_LOG_TO_LOGSERVER "TRACE_LOG_TO_LOGSERVER" //RMB跟踪日志上报,异常场景也要上报 +#define SYS_LOG_TO_LOGSERVER "SYS_LOG_TO_LOGSERVER" //业务日志上报 + //重定向指令 +#define REDIRECT_TO_CLIENT "REDIRECT_TO_CLIENT" //server将重定向指令推动给client + +#define MSG_ACK "MSG_ACK" //api 内部构造ack包命令字 + +//协议严格按照顺序,不要随便改变结构体的次序 +//严格按照encode和decode函数进行序列化和反序列化 + +//for uint64 + typedef union union64HN + { + unsigned int src[2]; + unsigned long long dest; + } union64HN; + +#define WEMQ_PROXY_MEMCPY(buf,bufLen,p,pLen) \ +if (bufLen > pLen) \ +{ \ + memcpy(buf, p, pLen); \ + return 0; \ +}\ +else \ + return -1; + +#define ENCODE_CHAR(buf,tmp)\ + *buf = tmp; \ + buf += sizeof(char); + +#define ENCODE_SHORT(buf,tmp)\ + *((short*)buf) = htons(tmp); \ + buf += sizeof(short); + +#define ENCODE_INT(buf,tmp)\ + *((int*)buf) = htonl(tmp); \ + buf += sizeof(int); + +#define ENCODE_LONG(buf,tmp)\ + *((long*)buf) = htonll_z(tmp); \ + buf += sizeof(long); + +#define DECODE_CHAR(tmp,buf,pBufLen) \ +if (*pBufLen < sizeof(char)) \ + return -2; \ + tmp = *((char*)(buf)); \ + buf += sizeof(char); \ + *pBufLen -= sizeof(char); + +#define DECODE_SHORT(tmp,buf,pBufLen)\ +if (*pBufLen < sizeof(short))\ + return -2; \ + tmp = ntohs(*((short*)buf)); \ + buf += sizeof(short); \ + *pBufLen -= sizeof(short); + +#define DECODE_INT(tmp,buf,pBufLen)\ +if (*pBufLen < sizeof(int))\ + return -2; \ + tmp = ntohl(*((int*)buf)); \ + buf += sizeof(int); \ + *pBufLen -= sizeof(int); + +#define DECODE_LONG(tmp,buf,pBufLen)\ +if (*pBufLen < sizeof(long))\ + return -2; \ + tmp = ntohll_z(*((long*)buf)); \ + buf += sizeof(long); \ + *pBufLen -= sizeof(long); + +#define ENCODE_CSTR_MEMCPY(buf, str, strLen) \ + ENCODE_CHAR(buf, strLen); \ + memcpy(buf, str, strLen); \ + buf += strLen; + +#define ENCODE_WSTR_MEMCPY(buf, str, strLen) \ + ENCODE_SHORT(buf, strLen); \ + memcpy(buf, str, strLen); \ + buf += strLen; + +/* +#define ENCODE_DWSTR_MEMCPY(buf, str, strLen) \ + ENCODE_INT(buf, strLen); \ + memcpy(buf, str, strLen); \ + buf += strLen; +*/ + +#define ENCODE_DWSTR_MEMCPY(buf, str, strLen) \ + memcpy(buf, str, strLen); \ + buf += strLen; + +#define DECODE_CSTR_MEMCPY(str, strLen, buf, pBufLen) \ + DECODE_CHAR(strLen, buf, pBufLen); \ + if (*pBufLen < strLen) return -2; \ + memcpy(str, buf, strLen); \ + buf += strLen; \ + *pBufLen -= strLen; + +#define DECODE_WSTR_MEMCPY(str, strLen, buf, pBufLen) \ + DECODE_SHORT(strLen, buf, pBufLen); \ + if (*pBufLen < strLen) return -2; \ + memcpy(str, buf, strLen);\ + buf += strLen; \ + *pBufLen -= strLen; +/* +#define DECODE_DWSTR_MEMCPY(str, strLen, buf, pBufLen) \ + DECODE_INT(strLen, buf, pBufLen); \ + if (*pBufLen < strLen) return -2; \ + memcpy(str, buf, strLen);\ + buf += strLen; \ + *pBufLen -= strLen; +*/ + +#define DECODE_DWSTR_MEMCPY(str, strLen, buf, pBufLen) \ + if (*pBufLen < strLen) return -2; \ + memcpy(str, buf, strLen);\ + buf += strLen; \ + *pBufLen -= strLen; + +//***************************0x01 心跳************************** +//请求 + typedef struct StHeartBeatReq + { + int pid; //进程号 + unsigned int uiCount; //心跳次数 + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StHeartBeatReq; + + int EncodeStHeartBeatReq (char *buf, int *pBufLen, + const StHeartBeatReq * pReq); + int DecodeHeartBeatReq (StHeartBeatReq * pReq, const char *buf, + const int bufLen); + +//回复 + typedef struct StHeartBeatRsp + { + unsigned int uiResult; //回复状态,0为ok,非0为不ok + int pid; //进程号 + unsigned int uiCount; //心跳次数 + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StHeartBeatRsp; + + int EncodeStHeartBeatRsp (char *buf, int *pBufLen, + const StHeartBeatRsp * pRsp); + int DecodeHeartBeatRsp (StHeartBeatRsp * pRsp, const char *buf, + const int bufLen); + +//***************************0x02 注册,建立连接************************** +//请求 + typedef struct StRegisterReq + { + int iPid; + char cSolaceHostLen; + char strSolaceHost[BYTES_LENGTH]; + char cSolaceVpnLen; + char strSolaceVpn[BYTES_LENGTH]; + char cSolaceUserLen; + char strSolaceUser[BYTES_LENGTH]; + char cSolacePwdLen; + char strSolacePwd[BYTES_LENGTH]; + char cConsumerIpLen; + char strConsumerIp[BYTES_LENGTH]; + char cConsumerSysIdLen; + char strConsumerSysId[BYTES_LENGTH]; + char cConsumerDcnLen; + char strConsumerDcn[BYTES_LENGTH]; + char cConsumerOrgIdLen; + char strConsumerOrgId[BYTES_LENGTH]; + char cConsumerVersionLen; + char strConsumerVersion[BYTES_LENGTH]; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StRegisterReq; + + int EncodeStRegisterReq (char *buf, int *pBufLen, + const StRegisterReq * pReq); + int DecodeStRegisterReq (StRegisterReq * pReq, const char *buf, + const int bufLen); + + typedef struct StRegisterRsp + { + unsigned int uiResult; + unsigned int uiCcdIndex; + unsigned int uiCcdFlow; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StRegisterRsp; + + int EncodeStRegisterRsp (char *buf, int *pBufLen, + const StRegisterRsp * pRsp); + int DecodeStRegisterRsp (StRegisterRsp * pRsp, const char *buf, + const int bufLen); + +//***********************************0x06 注册接收连接*********************************** + typedef struct StRegisterReceiveReq + { + unsigned int uiCcdIndex; + unsigned int uiCcdFlow; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StRegisterReceiveReq; + + int EncodeStRegisterReceiveReq (char *buf, int *pBufLen, + const StRegisterReceiveReq * pReq); + int DecodeStRegisterReceiveReq (StRegisterReceiveReq * pReq, + const char *buf, const int bufLen); + + typedef struct StRegisterReceiveRsp + { + unsigned int uiResult; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StRegisterReceiveRsp; + + int EncodeStRegisterReceiveRsp (char *buf, int *pBufLen, + const StRegisterReceiveRsp * pRsp); + int DecodeStRegisterReceiveRsp (StRegisterRsp * pRsp, const char *buf, + const int bufLen); + +//请求 + typedef struct StAddListenReq + { + char strServiceId[SERVICE_ID_LENGTH]; + char strSceneId[SCENE_ID_LENGTH]; + } StAddListenReq; + + int EncodeAddListenReq (char *buf, int *pBufLen, + const StAddListenReq * pReq); + int DecodeAddListenReq (StAddListenReq * pReq, const char *buf, + const int bufLen); + + typedef struct StAddListenRsp + { + unsigned int uiResult; //见last_error + char strServiceId[SERVICE_ID_LENGTH]; + char strSceneId[SCENE_ID_LENGTH]; + } StAddListenRsp; + + int EncodeAddListenRsp (char *buf, int *pBufLen, + const StAddListenRsp * pRsp); + int DecodeAddListenRsp (StAddListenRsp * pRsp, const char *buf, + const int bufLen); + +//***************************0x03 增加监听************************** + +//请求 + typedef struct StAddManageReq + { + char cManageTopicLength; + char strManageTopic[BYTES_LENGTH]; + } StAddManageReq; + + int EncodeAddManageReq (char *buf, int *pBufLen, + const StAddManageReq * pReq); + int DecodeAddManageReq (StAddManageReq * pReq, const char *buf, + const int bufLen); + + typedef struct StAddManageRsp + { + unsigned int uiResult; //见last_error + char cManageTopicLength; + char strManageTopic[BYTES_LENGTH]; + } StAddManageRsp; + + int EncodeAddManageRsp (char *buf, int *pBufLen, + const StAddManageRsp * pRsp); + int DecodeAddManageRsp (StAddManageRsp * pRsp, const char *buf, + const int bufLen); + +//***************************0x04 worker发包************************** +//请求 + enum WORKER_SEND_MSG_TYPE + { + SEND_EVENT_MSG_TYPE = 1, + SEND_RR_MSG_TYPE = 2, + SEND_ASYNC_RR_MSG_TYPE = 3, + SEND_REPLY_MSG_TYPE = 4, + }; + + typedef struct StSendMsgReq + { + unsigned int uiMsgType; //见WORKER_SEND_MSG_TYPE定义 + unsigned int uiWemqMsgLen; + unsigned int uiSendMsgSeq; + char strWemqMsg[MAX_MSG_WEMQ_MSG_SIZE]; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StSendMsgReq; + + int EncodeSendMsgReq (char *buf, int *pBufLen, const StSendMsgReq * pReq); + int DecodeSendMsgReq (StSendMsgReq * pReq, const char *buf, + const int bufLen); + +//回包 + typedef struct StSendMsgRsp + { + unsigned int uiResult; + unsigned int uiMsgType; //见WORKER_SEND_MSG_TYPE定义 + unsigned int uiRecvMsgSeq; //Worker send window size; + char cUuidLen; //消息uuid长度 + char strUuid[BYTES_LENGTH]; //消息uuid + } StSendMsgRsp; + +//return -1.空间不足 + int EncodeSendMsgRsp (char *buf, int *pBufLen, const StSendMsgRsp * pRsp); + int DecodeSendMsgRsp (StSendMsgRsp * pRsp, const char *buf, + const int bufLen); + +//***************************0x05 worker发送消息ack************************** +//请求,为避免其他业务代码错误导致把其他人的msg ack掉。因此这里将sessionId和sessionIndex、flowIndex做核对。 + typedef struct StAckMsgReq + { + unsigned int uiSessionIndex; + unsigned int uiFlowIndex; + unsigned long ulMsgId; + char cUuidLen; //消息uuid长度 + char strUuid[BYTES_LENGTH]; //消息uuid + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StAckMsgReq; + + int EncodeAckMsgReq (char *buf, int *pBufLen, const StAckMsgReq * pReq); + int DecodeAckMsgReq (StAckMsgReq * pReq, const char *buf, const int bufLen); + +//回包 + typedef struct StAckMsgRsp + { + unsigned int uiResult; + unsigned int uiSessionIndex; + unsigned int uiFlowIndex; + unsigned long ulMsgId; + char cUuidLen; //消息uuid长度 + char strUuid[BYTES_LENGTH]; //消息uuid + } StAckMsgRsp; + + int EncodeAckMsgRsp (char *buf, int *pBufLen, const StAckMsgRsp * pRsp); + int DecodeAckMsgRsp (StAckMsgRsp * pRsp, const char *buf, const int bufLen); + +//以下为proxy推送消息 +//***************************0x50 proxy下发消息************************** +//请求 + enum PUSH_MSG_TYPE + { + PUSH_QUEUE_MSG = 1, + PUSH_BROADCAST_MSG = 2, + PUSH_MANAGE_MSG = 3, + PUSH_RR_REPLY_MSG = 4, + }; + + typedef struct StPushMsgReq + { + char cWemqMsgType; + unsigned int uiSeq; + unsigned int uiWemqMsgLen; + char strWemqMsg[MAX_MSG_WEMQ_MSG_SIZE]; + char cReseveLength; //一字节长度 + char strReserve[BYTES_LENGTH]; //保留字段 + } StPushMsgReq; + + int EncodePushMsgReq (char *buf, int *pBufLen, const StPushMsgReq * pReq); + int DecodePushMsgReq (StPushMsgReq * pReq, const char *buf, + const int bufLen); + +//回包 + typedef struct StPushMsgRsp + { + unsigned int uiResult; + char cUuidLen; //消息uuid长度 + char strUuid[BYTES_LENGTH]; //消息uuid + } StPushMsgRsp; + + int EncodePushMsgRsp (char *buf, int *pBufLen, const StPushMsgRsp * pRsp); + int DecodePushMsgRsp (StPushMsgRsp * pRsp, const char *buf, + const int bufLen); + +//*************************************************wemq worker-proxy包格式***************************** +//msg的组成都是header + msgBuf,其中header的头4个字节为长度, + typedef struct StWemqHeader + { + unsigned int uiPkgLen; + unsigned int uiColorFlag; + unsigned short usCmd; + unsigned int uiSessionId; + unsigned int uiSeq; + unsigned int uiReserved; + } StWemqHeader; + +#define MAX_WEMQ_HEADER_LEN (4096) +#define MAX_WEMQ_BODY_LEN (3 * 1024 * 1024) + typedef struct StWeMQMSG + { + unsigned int uiTotalLen; + unsigned int uiHeaderLen; + char cStrJsonHeader[MAX_WEMQ_HEADER_LEN]; + char cStrJsonBody[MAX_WEMQ_BODY_LEN]; + } StWeMQMSG; + + int GetWemqHeaderLen (); + int EncodeWemqHeader (char *buf, int *pBufLen, + const StWemqHeader * pHeader); + int DecodeWemqHeader (StWemqHeader * pHeader, const char *buf, + const int bufLen); + int DecodeWeMQMsg (StWeMQMSG * pMsg, const char *buf, const int bufLen); + +//��ʽ������������ + int GetAckMsgReqLength (const StAckMsgReq * pReq); + int GetAddListenReqLegth (const StAddListenReq * pReq); + int GetAddManageReqLegth (const StAddManageReq * pReq); + int GetPushMsgReqLegth (const StPushMsgReq * pReq); + int GetRegisterReceiveReqLegth (const StRegisterReceiveReq * pReq); + int GetRegisterReqLegth (const StRegisterReq * pReq); + int GetSendMsgReqLength (const StSendMsgReq * pReq); + int GetStHeartBeatReqLegth (const StHeartBeatReq * pReq); + +#ifdef __cplusplus +} +#endif +//#pragma pack() +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_tcp.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_tcp.h new file mode 100644 index 0000000000..4bf9c5e412 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_tcp.h @@ -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. + +#ifndef _TCP_SOCKET_FOR_WEMQ_H_ +#define _TCP_SOCKET_FOR_WEMQ_H_ +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + int wemq_tcp_connect (const char *ip, uint16_t port, int timeout); + int wemq_tcp_send (int fd, void *msg, uint32_t totalLen, uint32_t headerLen, + int iTimeOut, SSL * ssl); + int wemq_tcp_recv (int fd, void *msg, uint32_t * len, int iTimeout, + SSL * ssl); + + void wemq_getsockename (int fd, char *ip, uint32_t len, int *port); + void wemq_getpeername (int fd, char *ip, uint32_t len, int *port); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_thread.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_thread.h new file mode 100644 index 0000000000..670c070fd3 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_thread.h @@ -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. + +#ifndef _WEMQ_THREAD_ +#define _WEMQ_THREAD_ + +#include +#include "rmb_define.h" +#define MAX_EVENT 10 +#define TCP_PKG_LEN_BTYES 4 + +#ifdef _WEMQ_THREAD_DEBUG_ +#define ASSERT(A) assert((A)) +#else +#define ASSERT(A) ((void)(0)) +#endif +enum +{ + THREAD_STATE_INIT = 0, + THREAD_STATE_CONNECT, + THREAD_STATE_REGI, + THREAD_STATE_OK, + THREAD_STATE_CLOSE, //准备关闭状态 + THREAD_STATE_SERVER_BREAK, //服务端退出状态 + THREAD_STATE_BREAK, + THREAD_STATE_RECONNECT, + THREAD_STATE_DESTROY, + THREAD_STATE_EXIT +}; + +enum +{ + THREAD_MSG_CMD_BEAT = 0x01, + THREAD_MSG_CMD_REGI = 0x02, + THREAD_MSG_CMD_ADD_LISTEN = 0x03, + THREAD_MSG_CMD_SEND_MSG = 0x04, + THREAD_MSG_CMD_SEND_MSG_ACK = 0x05, + THREAD_MSG_CMD_ADD_MANAGE = 0x06, + THREAD_MSG_CMD_SEND_REQUEST = 0x07, + THREAD_MSG_CMD_SEND_REQUEST_ASYNC = 0x08, + THREAD_MSG_CMD_SEND_REPLY = 0x09, + THREAD_MSG_CMD_START = 0x0a, + THREAD_MSG_CMD_SEND_PUSH = 0x50, + THREAD_MSG_CMD_SEND_CLIENT_GOODBYE = 0x0b, + THREAD_MSG_CMD_SEND_LOG = 0x10, + THREAD_MSG_CMD_RECV_MSG_ACK = 0x11 +}; +/* +typedef struct StWemqThreadMsg +{ + unsigned int m_iCmd; + StWemqHeader m_stWemqHeader; + void* m_stReq; +}StWemqThreadMsg; +*/ +/* +typedef struct WemqThreadCtx +{ +// STRUCT_WEMQ_KFIFO(StWemqThreadMsg, 1024)* m_ptFifo; + stContextProxy* m_ptProxyContext; + + int m_iThreadId; + char* m_pRecvBuff; + char* m_pSendBuff; + + //cache msg which from user thread; + StWemqThreadMsg m_stWemqThreadMsg; + int m_iWemqThreadMsgHandled; + + StRegisterReq m_stReqForRegister; + StAddManageReq m_stReqForAddManage; + StAddListenReq m_stReqForAddListen; + + StWemqHeader m_stWemqHeader; + + StTopicList* m_ptTopicList; + + //for epoll + int m_iEpollFd; + struct epoll_event m_stEv; + struct epoll_event* m_ptEvents; + + int m_iSockFd; + int m_iLastState; + int m_iState; + int m_contextType; + +}WemqThreadCtx; +*/ +#define GetWemqThreadMsgLen() (sizeof(StWemqThreadMsg)) + +int32_t wemq_thread_state_init (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_connect (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_regi (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_ok (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_break (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_reconnect (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_state_destory (WemqThreadCtx * pThreadCtx); +int32_t wemq_thread_run (WemqThreadCtx * pThreadCtx); +int32_t check_dyed_msg (StRmbMsg * rmbMsg); +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/include/wemq_topic_list.h b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_topic_list.h new file mode 100644 index 0000000000..2d0971e1ad --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/include/wemq_topic_list.h @@ -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. + +#ifndef _WEMQ_TOPIC_LIST_H_ +#define _WEMQ_TOPIC_LIST_H_ +#include +#include +#include +#include + +#define WEMQ_TOPIC_MAX_LEN 100 + +typedef struct StWemqTopicProp +{ + char cServiceId[32]; + char cScenario[32]; + char cTopic[WEMQ_TOPIC_MAX_LEN]; + int flag; //flag=0, serviceid flag=1, topic + struct StWemqTopicProp *next; +} StWemqTopicProp; + +typedef struct StWemqTopicList +{ + StWemqTopicProp *next; + StWemqTopicProp *tail; +} StWemqTopicList; + +typedef int (*WEMQ_DEC_FUNC) (StWemqTopicProp * pArg); + +void wemq_topic_list_init (StWemqTopicList * ptTopicList); +int32_t wemq_topic_list_delete (StWemqTopicList * pt); +int32_t wemq_topic_list_add_node (StWemqTopicList * pt, + StWemqTopicProp * ptpp); +int32_t wemq_topic_list_find_node (StWemqTopicList * pt, + StWemqTopicProp * ptpp, + StWemqTopicProp ** pos); +int32_t wemq_topic_list_del_node (StWemqTopicList * pt, + StWemqTopicProp * ptpp); +int32_t wemq_topic_list_is_empty (StWemqTopicList * pt); +int32_t wemq_topic_list_clear (StWemqTopicList * ptTopicList); +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/makefile b/eventmesh-sdks/eventmesh-sdk-c/makefile new file mode 100644 index 0000000000..116182478f --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/makefile @@ -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. + +CC=gcc +RANLIB = ranlib + +RMB_VERSION=$(shell grep "RMBVERSION" include/rmb_define.h|grep -v "RMBVERSIONFORBIZ"|awk -F " |\"" '{print $$4}') + +INC = -I./include -I./src + +DIR_THIRD_PARTY = ./third_party + +DIR_CURL = $(DIR_THIRD_PARTY)/curl +INC_CURL = -I$(DIR_CURL)/include +LIB_A_CURL = $(DIR_THIRD_PARTY)/libcurl.a +LIB_CURL = -L$(DIR_THIRD_PARTY) -lcurl + +DIR_JSONC = $(DIR_THIRD_PARTY)/json-c +DIR_BUILD_JSONC = $(DIR_JSONC)/cmake/build +INC_JSONC = -I$(DIR_JSONC) -I$(DIR_BUILD_JSONC) +LIB_A_JSONC = $(DIR_THIRD_PARTY)/libjson-c.a +LIB_JSONC = -L$(DIR_THIRD_PARTY) -ljson-c + +LIB_UUID = -luuid + +LIB_OPENSSL = -lssl -lcrypto + +INC += $(INC_CURL) $(INC_JSONC) +LIB = $(LIB_CURL) $(LIB_JSONC) $(LIB_UUID) $(LIB_OPENSSL) + +CFLAGS=-Wall -g -gstabs+ -ggdb -fPIC -Wunused-function + +TARGET_STATIC = librmb.a +TARGET_DYNAMIC = librmb.so +TARGET = $(TARGET_STATIC) $(TARGET_DYNAMIC) + +OBJ = $(patsubst %.c,%.o,$(wildcard ./src/*.c)) + +all:$(TARGET) + +$(LIB_A_CURL): + @echo + @echo "Building $^ ==> $@..." + @cd $(DIR_CURL) && autoreconf -fi && ./configure --without-ssl + @cd $(DIR_CURL) && make + @cp -f $(DIR_CURL)/./lib/.libs/libcurl.a $@ + +$(LIB_A_JSONC): + @echo + @echo "Building $^ ==> $@..." + @mkdir -p $(DIR_BUILD_JSONC) + @cd $(DIR_BUILD_JSONC) && cmake ../.. + @cd $(DIR_JSONC)/cmake/build && make + @cp $(DIR_JSONC)/cmake/build/libjson-c.a $@ + +./tmp/libm.a: $(OBJ) + @echo + @echo "Building $^ ==> $@..." + @-mkdir -p ./tmp + $(AR) cq $@ $^ + $(RANLIB) $@ + +$(TARGET_STATIC): $(LIB_A_CURL) $(LIB_A_JSONC) ./tmp/libm.a + @echo + @echo "Building $^ ==> $@..." + @cp -f $(LIB_A_CURL) ./tmp + @cp -f $(LIB_A_JSONC) ./tmp + @rm -f $@ + $(AR) cqT $@ ./tmp/*.a && echo -e 'create $@\naddlib $@\nsave\nend' | $(AR) -M + +$(TARGET_DYNAMIC): $(LIB_A_CURL) $(LIB_A_JSONC) $(OBJ) + @echo + @echo "Building $^ ==> $@..." + @rm -f $@ + $(CC) -shared -fPIC $(CFLAGS) -o $@ $(OBJ) $(LIB) + +%.o: %.c + $(CC) $(CFLAGS) $(INC) -c $^ -o $@ + +.PHONY: clean +clean: + rm -rf $(TARGET) $(OBJ) ./tmp + +demo: $(TARGET_STATIC) + @echo + @echo "Building $^ ==> $@..." + $(CC) -o $@ examples/demo.c $(CCFLAGS) -I./include -L./ -l:librmb.a -luuid $(LIB_OPENSSL) -lz -pthread -lrt -dl -static-libgcc diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/common.h b/eventmesh-sdks/eventmesh-sdk-c/src/common.h new file mode 100644 index 0000000000..1c2db39639 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/common.h @@ -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. + +#ifndef COMMON_H_ +#define COMMON_H_ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "json.h" +#include "rmb_define.h" + +// context proxy新增结构 + typedef struct json_object WEMQJSON; + typedef struct json_object PROPERTY; + + WEMQJSON *rmb_pub_encode_byte_body_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg); + WEMQJSON *rmb_pub_encode_property_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/message_log_api.c b/eventmesh-sdks/eventmesh-sdk-c/src/message_log_api.c new file mode 100644 index 0000000000..ee58205a7d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/message_log_api.c @@ -0,0 +1,397 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include "common.h" +#include "message_log_api.h" +#include "wemq_thread.h" + +#define gettidv1() syscall(__NR_gettid) +#define gettidv2() syscall(SYS_gettid) + +static int get_log_id (char *clogId, int size) +{ + if (0 != rmb_msg_random_uuid (clogId, size)) + { + return -1; + } + + int i = 0; + for (i = 0; i < size; i++) + { + if (*(clogId + i) == '-') + { + *(clogId + i) = '0'; + } + } + + return 0; +} + +/*headerJson={“code”:0,”command”:”SYS_LOG_TO_LOGSERVER”} + bodyJson={“id”:”839232”,”consumerId”:”5982”,”logName”:”test”,”logTimestamp”:0, + ”content”:”test”,”logType”:”sys”,”lang”:”c”,”level”:”debug”,”processId”:5176,”threadId”:0,”consumerSvrId”:”dsi”,”extFields”:{}} +*/ + +int rmb_send_sys_log_for_api (stContextProxy * pContextProxy, + const char *iLogLevel, const char *cConsumerId, + const char *cLogName, const char *cContent, + const char *extFields) +{ + + if (pContextProxy == NULL || NULL == extFields) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy or extFields is null"); + return -1; + } + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_LOG; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonHeader failed"); + return -1; + } + + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (SYS_LOG_TO_LOGSERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonBody failed"); + json_object_put (jsonHeader); + return -1; + } + char cLogId[33] = { 0 }; + + if (0 != get_log_id (cLogId, sizeof (cLogId))) + { + LOGRMB (RMB_LOG_ERROR, "get_log_id failed"); + return -1; + } + + GetRmbNowLongTime (); + json_object_object_add (jsonBody, LOG_MSG_COM_ID, + json_object_new_string (cLogId)); + json_object_object_add (jsonBody, LOG_MSG_COM_CONSUMERID, + json_object_new_string (cConsumerId)); + json_object_object_add (jsonBody, LOG_MSG_COM_LOGNAME, + json_object_new_string (cLogName)); + json_object_object_add (jsonBody, LOG_MSG_COM_TIMESTAMP, + json_object_new_int64 (pRmbStConfig->ulNowTtime)); + json_object_object_add (jsonBody, LOG_MSG_COM_CONTENT, + json_object_new_string (cContent)); + json_object_object_add (jsonBody, LOG_MSG_COM_LOGTYPE, + json_object_new_string ("sys")); + json_object_object_add (jsonBody, LOG_MSG_COM_LANG, + json_object_new_string ("c")); + json_object_object_add (jsonBody, LOG_MSG_COM_PROCESSID, + json_object_new_int ((int) getpid ())); + json_object_object_add (jsonBody, LOG_MSG_COM_THREADID, + json_object_new_int64 ((long int) gettidv1 ())); + json_object_object_add (jsonBody, LOG_MSG_COM_CONSUMERSVRID, + json_object_new_string (pRmbStConfig->cHostIp)); + json_object_object_add (jsonBody, LOG_MSG_COM_LEVEL, + json_object_new_string (iLogLevel)); + + WEMQJSON *jsonExtFields = json_tokener_parse (extFields); + WEMQJSON *tmp = NULL; + if (jsonExtFields == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_tokener_parse extFields failed"); + tmp = json_tokener_parse ("{}"); + json_object_object_add (jsonBody, LOG_MSG_COM_EXTFIELDS, tmp); + } + else + { + json_object_object_add (jsonBody, LOG_MSG_COM_EXTFIELDS, jsonExtFields); + } + const char *header_str = json_object_get_string (jsonHeader); + + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_get_string for header is null"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -2; + } + stThreadMsg.m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_INFO, "Gen thread msg header succ, len=%d, %s", + stThreadMsg.m_iHeaderLen, header_str); + stThreadMsg.m_pHeader = + (char *) malloc (stThreadMsg.m_iHeaderLen * sizeof (char) + 1); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for m_pHeader failed, errno=%d", errno); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + strncpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + + stThreadMsg.m_iBodyLen = strlen (body_str); + stThreadMsg.m_pBody = + (char *) malloc (stThreadMsg.m_iBodyLen * sizeof (char) + 1); + if (stThreadMsg.m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + memcpy (stThreadMsg.m_pBody, body_str, stThreadMsg.m_iBodyLen); + stThreadMsg.m_pBody[stThreadMsg.m_iBodyLen] = '\0'; + + json_object_put (jsonBody); + json_object_put (jsonHeader); + + int iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!,iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return -5; + } + else + { + LOGRMB (RMB_LOG_DEBUG, "put sys log msg to fifo"); + return 0; + } +} + +/* +header=Header{cmd=TRACE_LOG_TO_LOGSERVER, code=0, msg='null', seq='null'}, body=RmbTraceLog{level=debug, logTimestamp=1525674893639, +logPoint=LOG_ERROR_POINT, message='null', model='model', retCode='retCode', retMsg='retMsg', lang='c', extFields={key=value}}} +*/ + +int rmb_send_log_for_error (stContextProxy * pContextProxy, int errCode, + char *errMsg, StRmbMsg * ptSendMsg) +{ + if (pRmbStConfig->iApiLogserverSwitch == 0) + { + return 0; + } + + if (pContextProxy == NULL || NULL == ptSendMsg) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy or ptSendMsg is null"); + return -1; + } + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_LOG; + + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (TRACE_LOG_TO_LOGSERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + json_object_put (jsonHeader); + return -1; + } + WEMQJSON *jsonMessage = json_object_new_object (); + if (jsonMessage == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonMessage, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (THREAD_MSG_CMD_SEND_LOG, ptSendMsg); + if (jsonBodyProperty == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonBody); + return -1; + } + + json_object_object_add (jsonMessage, MSG_BODY_PROPERTY_JSON, + jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (THREAD_MSG_CMD_SEND_LOG, ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonMessage, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *message_str = json_object_get_string (jsonMessage); + if (message_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + return -1; + } + + json_object_object_add (jsonBody, "retCode", json_object_new_int (errCode)); + json_object_object_add (jsonBody, "retMsg", + json_object_new_string (errMsg)); + json_object_object_add (jsonBody, "level", + json_object_new_string ("error")); + json_object_object_add (jsonBody, "logPoint", + json_object_new_string (LOG_ERROR_POINT)); + json_object_object_add (jsonBody, "model", + json_object_new_string ("model")); + json_object_object_add (jsonBody, "lang", json_object_new_string ("c")); + json_object_object_add (jsonBody, "message", + json_object_new_string (message_str)); + + const char *header_str = json_object_get_string (jsonHeader); + + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_get_string for header is null"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + return -2; + } + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + return -1; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + + stThreadMsg.m_pHeader = + (char *) malloc (stThreadMsg.m_iHeaderLen * sizeof (char) + 1); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for m_pHeader failed, errno=%d", errno); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + return -1; + } + strncpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + stThreadMsg.m_iBodyLen = strlen (body_str); + stThreadMsg.m_pBody = + (char *) malloc (stThreadMsg.m_iBodyLen * sizeof (char) + 1); + if (stThreadMsg.m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + return -1; + } + memcpy (stThreadMsg.m_pBody, body_str, stThreadMsg.m_iBodyLen); + stThreadMsg.m_pBody[stThreadMsg.m_iBodyLen] = '\0'; + LOGRMB (RMB_LOG_INFO, "Gen error log succ, header :%s, body:%s", header_str, + body_str); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!,iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return -5; + } + else + { + LOGRMB (RMB_LOG_DEBUG, "error log msg put into fofo"); + return 0; + } +} + +/** + * 提供给业务调用,用于业务主动上报logserver + */ +int rmb_log_for_common (StContext * pStContext, const char *iLogLevel, + const char *cLogName, const char *content, + const char *extFields) +{ + if (pRmbStConfig->iApiLogserverSwitch == 0) + { + return 0; + } + stContextProxy *pContextProxy = pStContext->pContextProxy; + int iRet = + rmb_send_sys_log_for_api (pContextProxy, iLogLevel, + pRmbStConfig->cConsumerSysId, cLogName, content, + extFields); + return iRet; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_access_config.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_access_config.c new file mode 100644 index 0000000000..8d39edc1a3 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_access_config.c @@ -0,0 +1,827 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include "curl/curl.h" +#include "common.h" +#include "rmb_define.h" +#include "rmb_http_client.h" + +#define WEMQ_PROXY_MAX_SIZE (512) +#define WEMQ_PROXY_BUFFER_SIZE (262144) // 256K +//#define WEMQ_PROXY_SERVER_MAX_TIME (3600) // 1H +#define WEMQ_PROXY_SERVER_MAX_TIME (1 * 60 * 1000000) // 1m + +#define atomic_set(x, y) __sync_lock_test_and_set((x), (y)) + +typedef struct StWemqProxy +{ + char host[100]; + char idc[30]; + unsigned int port; + unsigned int weight; + unsigned int index; + + long failed_time; // 0: 没有失败; >0: 失败时间戳 + int flag; //用于初始连接时,该host是否已连接过 +} StWemqProxy; + +static struct StWemqProxy _wemq_proxy_list[WEMQ_PROXY_MAX_SIZE]; +static int _wemq_proxy_list_num = 0; // proxy个数 +static int _wemq_proxy_list_used = -1; // 当前使用proxy +static int _wemq_proxy_weight_tol = 0; // 权重总和 + +static int _wemq_proxy_inited = 0; + +static pthread_mutex_t __wemq_proxy_rmutex; + +int rmb_get_wemq_proxy_list_num () +{ + return _wemq_proxy_list_num; +} + +int rmb_get_wemq_proxy_list_used () +{ + return _wemq_proxy_list_used; +} + +static void ltrim (char *s) +{ + char *p = s; + int len = 0; + + if (s == NULL || *s == '\0') + { + return; + } + while (*p != '\0' && (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')) + { + p++; + len++; + } + memmove (s, p, strlen (s) - len + 1); +} + +static void rtrim (char *s) +{ + int i; + + if (s == NULL || *s == '\0') + { + return; + } + i = strlen (s) - 1; + while ((s[i] == ' ' || + s[i] == '\t' || s[i] == '\n' || s[i] == '\r') && i >= 0) + { + s[i] = '\0'; + i--; + } +} + +static void trim (char *s) +{ + ltrim (s); + rtrim (s); +} + +static int _wemq_proxy_cmp (const void *val1, const void *val2) +{ + const StWemqProxy *proxy1 = (const StWemqProxy *) val1; + const StWemqProxy *proxy2 = (const StWemqProxy *) val2; + + if (proxy1->weight > proxy2->weight) + return 1; + if (proxy1->weight < proxy2->weight) + return -1; + return 0; +} + +/* +返回示例 +{ +"wemq-proxy-servers" : "10.255.1.144:10000#3;;127.0.0.1:36000#1;" +} +服务器列表格式 +host:port#weight; +host:port#weight;host:port#weight; +*/ +static int _wemq_proxy_load_item (StWemqProxy * pproxy, const char *pstr, + size_t len) +{ + char weight[64] = ""; + char idc[32] = ""; + char port[64] = ""; + int index1 = -1; // ':'位置 + int index2 = -1; // '#'位置 + int index3 = -1; // '|' 位置 + int begin = 0; + int size = 0; + int i = 0; + + if (pstr == NULL || pproxy == NULL || len == 0) + { + return -1; + } + + for (i = 0; i < (int) len; i++) + { + if (pstr[i] == ':') + { + if (index1 != -1) + { + return -2; + } + index1 = i; + } + else if (pstr[i] == '#') + { + if (index2 != -1) + { + return -2; + } + index2 = i; + } + else if (pstr[i] == '|') + { + if (index3 != -1) + { + return -2; + } + index3 = i; + } + } + + // 确认格式是否正确 + if (index1 == -1 || index2 == -1 || index1 >= index2 || index2 >= index3) + { + return -2; + } + + // IP + if (index1 > 100 || index1 == 0) + { + return -3; + } + memcpy (pproxy->host, pstr, index1); + pproxy->host[index1] = '\0'; + + // port + begin = index1 + 1; + size = index2 - begin; + if (size > 64 || size == 0) + { + return -3; + } + memcpy (port, &pstr[begin], size); + port[size] = '\0'; + + // weight + begin = index2 + 1; + size = index3 - begin; + if (size > 64 || size == 0) + { + return -3; + } + memcpy (weight, &pstr[begin], size); + weight[size] = '\0'; + + // idc + begin = index3 + 1; + size = len - begin; + if (size > 64 || size == 0) + { + return -3; + } + memcpy (pproxy->idc, &pstr[begin], size); + pproxy->idc[size] = '\0'; + + pproxy->port = atoi (port); + pproxy->weight = atoi (weight); + + if (pproxy->port == 0 || pproxy->weight == 0) + { + return -4; + } + + pproxy->flag = 0; + return 0; +} + +static int _wemq_proxy_load_by_http (StWemqProxy * pproxy, size_t size, + const char *url, long timeout) +{ + + int ret = 0; + if (pproxy == NULL || url == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pproxy or url is null"); + return -1; + } + + char *servers = NULL; + struct rmb_http_buffer req; + req.len = 0; + req.data = (char *) malloc (sizeof (char)); + if (req.data == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for req.data failed"); + return -1; + } + + if ((ret = rmb_http_easy_get (url, (void *) &req, timeout)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_http_easy_get error,iRet=%d", ret); + ret = -2; + goto _LOAD_ITEM_END; + } + + servers = (char *) malloc (sizeof (char) * (req.len + 1)); + if (servers == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for servers failed"); + free (req.data); + req.data = NULL; + return -1; + } + + LOGRMB (RMB_LOG_INFO, "_wemq_proxy_load_by_http:[resp:len=%u,%s]!", + (unsigned int) req.len, req.data); + if (req.len <= 2) + return -1; + // 解析json字符串 + + WEMQJSON *json = json_tokener_parse (req.data); + WEMQJSON *wemq_proxy_servers = NULL; + if (json == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: json_tokener_parse error!"); + ret = -3; + goto _LOAD_ITEM_END; + } + + char *config_param = "wemqAccessServer"; + if (strstr (url, "wemqAccessServer") == NULL) + config_param = pRmbStConfig->strDepartMent; + if (!json_object_object_get_ex (json, config_param, &wemq_proxy_servers)) + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: json_object_object_get_ex error!"); + ret = -3; + json_object_put (json); + goto _LOAD_ITEM_END; + } + + const char *pservers = json_object_get_string (wemq_proxy_servers); + if (pservers != NULL) + { + snprintf (servers, WEMQ_PROXY_BUFFER_SIZE, "%s", pservers); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: wemqAccessServer is null"); + } + json_object_put (json); + + LOGRMB (RMB_LOG_INFO, "_wemq_proxy_load_by_http: [servers:%s]!", servers); + + json = json_tokener_parse (servers); + wemq_proxy_servers = NULL; + if (json == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: json_tokener_parse error!"); + ret = -3; + goto _LOAD_ITEM_END; + } + + //如果当前子系统有特定的access,没有就默认 + if (!json_object_object_get_ex + (json, pRmbStConfig->cConsumerSysId, &wemq_proxy_servers)) + { + LOGRMB (RMB_LOG_INFO, + "current subsystem does not have special access list"); + if (!json_object_object_get_ex + (json, "wemqAccessServer", &wemq_proxy_servers)) + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: json_object_object_get_ex error!"); + ret = -3; + json_object_put (json); + goto _LOAD_ITEM_END; + } + + } + + pservers = json_object_get_string (wemq_proxy_servers); + if (pservers != NULL) + { + snprintf (servers, WEMQ_PROXY_BUFFER_SIZE, "%s", pservers); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "_wemq_proxy_load_by_http: wemqAccessServer is null"); + } + json_object_put (json); + + // 解析每个字段 + trim (servers); + { + char *item = NULL; + char *saveptr = NULL; + char *ptr = servers; + int i = 0; + + while ((item = strtok_r (ptr, ";", &saveptr)) != NULL) + { + if (i >= (int) size) + { + LOGRMB (RMB_LOG_WARN, + " [index: %d] [size: %zu] _wemq_proxy_load_by_http: servers too more!\n", + i, size); + break; + } + if (_wemq_proxy_load_item (&pproxy[i], item, strlen (item)) == 0) + { + i++; + } + else + { + LOGRMB (RMB_LOG_WARN, + "[item: %s] _wemq_proxy_load_by_http: _wemq_proxy_load_item error!\n", + item); + } + ptr = NULL; + } + if (i == 0) + { + LOGRMB (RMB_LOG_ERROR, "_wemq_proxy_load_by_http: servers is 0!\n"); + } + + ret = i; + } + +_LOAD_ITEM_END: + if (req.data != NULL) + { + free (req.data); + req.data = NULL; + } + if (servers != NULL) + { + free (servers); + servers = NULL; + } + return ret; +} + +static int _wemq_proxy_save (StWemqProxy * pproxy, size_t size, + const char *path) +{ + FILE *fp = NULL; + int i = 0; + + if ((fp = fopen (path, "w")) == NULL) + { + LOGRMB (RMB_LOG_ERROR, "[path: %s] _wemq_proxy_save: fopen error!\n", + path); + return -1; + } + for (i = 0; i < (int) size; i++) + { + fprintf (fp, "%s:%u#%u\n", pproxy[i].host, pproxy[i].port, + pproxy[i].weight); + } + fclose (fp); + return 0; +} + +//int wemq_proxy_load_servers(char* url, long timeout, const char* path) +int wemq_proxy_load_servers (const char *url, long timeout) +{ + int ret = 0; + int tol = 0; + int i = 0; + int j = 0; + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return 0; + } + + if (_wemq_proxy_inited == 0) + { + _wemq_proxy_inited = 1; + pthread_mutex_init (&__wemq_proxy_rmutex, NULL); + } + + int tmp_wemq_proxy_list_num = 0; + struct StWemqProxy tmp_wemq_proxy_list[WEMQ_PROXY_MAX_SIZE]; + + memset (tmp_wemq_proxy_list, 0, sizeof (StWemqProxy) * WEMQ_PROXY_MAX_SIZE); + + //1. 通过HTTP请求配置中心 + ret = + _wemq_proxy_load_by_http (tmp_wemq_proxy_list, WEMQ_PROXY_MAX_SIZE, url, + timeout); + if (ret <= 0 && (strstr (url, "wemqAccessServer") == NULL)) + { + LOGRMB (RMB_LOG_WARN, "get wemq proxy departMent ip list failed,url=%s", + url); + return -1; + } + if (ret <= 0) + { + LOGRMB (RMB_LOG_ERROR, "get wemq proxy ip list failed,url=%s", url); + return -1; + } + tmp_wemq_proxy_list_num = ret; + + //2. 排序 + qsort (tmp_wemq_proxy_list, tmp_wemq_proxy_list_num, sizeof (StWemqProxy), + _wemq_proxy_cmp); + + //3. 权重相加 + for (i = 0; i < tmp_wemq_proxy_list_num; i++) + { + tol += tmp_wemq_proxy_list[i].weight; + } + _wemq_proxy_weight_tol = tol; + int equal_flag = 0; + + if (tmp_wemq_proxy_list_num == _wemq_proxy_list_num) + { + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if (strcmp (_wemq_proxy_list[i].host, tmp_wemq_proxy_list[i].host) != 0 + || _wemq_proxy_list[i].port != tmp_wemq_proxy_list[i].port + || _wemq_proxy_list[i].weight != tmp_wemq_proxy_list[i].weight) + { + equal_flag = 1; + break; + } + } + //配置中心和本地的配置相同 + if (equal_flag == 0) + return 0; + } + //打印配置中心和本地的配置 + for (i = 0; i < _wemq_proxy_list_num; i++) + { + LOGRMB (RMB_LOG_DEBUG, + "[local address %d: host,%s|port,%u|idc:%s|weight,%u|index,%u|failed_time,%ld|flag,%d", + i, _wemq_proxy_list[i].host, _wemq_proxy_list[i].port, + _wemq_proxy_list[i].idc, _wemq_proxy_list[i].weight, + _wemq_proxy_list[i].index, _wemq_proxy_list[i].failed_time, + _wemq_proxy_list[i].flag); + } + for (j = 0; j < tmp_wemq_proxy_list_num; j++) + { + LOGRMB (RMB_LOG_DEBUG, + "[configcenter address %d: host,%s|port,%u|idc:%s|weight,%u|index,%u|failed_time,%ld|flag,%d", + j, tmp_wemq_proxy_list[j].host, tmp_wemq_proxy_list[j].port, + tmp_wemq_proxy_list[j].idc, tmp_wemq_proxy_list[j].weight, + tmp_wemq_proxy_list[j].index, tmp_wemq_proxy_list[j].failed_time, + tmp_wemq_proxy_list[j].flag); + } + + pthread_mutex_lock (&__wemq_proxy_rmutex); + //比较缓存数据和配置中心获取的数据,保留缓存数据中的flag和failedtime + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if (_wemq_proxy_list[i].failed_time == 0 && _wemq_proxy_list[i].flag == 0) + continue; + for (j = 0; j < tmp_wemq_proxy_list_num; j++) + { + if (strcmp (_wemq_proxy_list[i].host, tmp_wemq_proxy_list[j].host) == 0 + && _wemq_proxy_list[i].port == tmp_wemq_proxy_list[j].port) + { + tmp_wemq_proxy_list[j].failed_time = _wemq_proxy_list[i].failed_time; + tmp_wemq_proxy_list[j].flag = _wemq_proxy_list[i].flag; + } + } + } + //更新缓存数据 + memset (_wemq_proxy_list, 0, sizeof (StWemqProxy) * WEMQ_PROXY_MAX_SIZE); + memcpy (_wemq_proxy_list, tmp_wemq_proxy_list, + sizeof (StWemqProxy) * tmp_wemq_proxy_list_num); + _wemq_proxy_list_num = tmp_wemq_proxy_list_num; + _wemq_proxy_list_used = -1; + pthread_mutex_unlock (&__wemq_proxy_rmutex); + + return 0; +} + +int wemq_proxy_get_server (char *host, size_t size, unsigned int *port) +{ + int now_index = -1; + int tmp = -1; + int wemq_proxy_usable_server_list[_wemq_proxy_list_num]; + long now_time = 0; + struct timeval tv; + + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + *port = pRmbStConfig->cWemqProxyPort; + snprintf (host, size, "%s", pRmbStConfig->cWemqProxyIp); + return 1; + } + + pthread_mutex_lock (&__wemq_proxy_rmutex); + if (_wemq_proxy_list_num <= 0) + { + pthread_mutex_unlock (&__wemq_proxy_rmutex); + LOGRMB (RMB_LOG_ERROR, "get proxy list number is:%d", + _wemq_proxy_list_num); + *port = 0; + memset (host, 0x00, sizeof (char) * size); + return 2; + } + + //从可以连接的ip中选取 + int wemq_proxy_usable_sever_weight = 0; + int wemq_proxy_usable_count = 0; + wemq_proxy_get_usable_server_list (wemq_proxy_usable_server_list, + &wemq_proxy_usable_sever_weight, + &wemq_proxy_usable_count); + //LOGRMB(RMB_LOG_DEBUG, "final count: %d | final weight: %d", wemq_proxy_usable_count, wemq_proxy_usable_sever_weight); + if (wemq_proxy_usable_count == 0) + { + pthread_mutex_unlock (&__wemq_proxy_rmutex); + LOGRMB (RMB_LOG_ERROR, "local proxy list all in black list"); + *port = 0; + memset (host, 0x00, sizeof (char) * size); + return 2; + } + else if (wemq_proxy_usable_count == 1) + { + now_index = wemq_proxy_usable_server_list[0]; + } + else + { + + //use weight + gettimeofday (&tv, NULL); + now_time = tv.tv_sec * 1000000 + tv.tv_usec; + srand ((unsigned int) now_time); + int random_index = rand () % wemq_proxy_usable_sever_weight; + int i = 0; + int tmp_weight = 0; + int tmp_index = 0; + for (; i < wemq_proxy_usable_count; i++) + { + tmp_index = wemq_proxy_usable_server_list[i]; + tmp_weight += _wemq_proxy_list[tmp_index].weight; + if (random_index < tmp_weight) + { + //LOGRMB(RMB_LOG_DEBUG, "choose host: %s | failed_time:%ld", _wemq_proxy_list[tmp_index].host, _wemq_proxy_list[tmp_index].failed_time); + now_index = tmp_index; + break; + } + } + } + gettimeofday (&tv, NULL); + now_time = tv.tv_sec * 1000000 + tv.tv_usec; + if ((_wemq_proxy_list[now_index].failed_time + + WEMQ_PROXY_SERVER_MAX_TIME) <= now_time) + { + atomic_set (&_wemq_proxy_list[now_index].failed_time, 0); + } + + // } while (tmp != now_index); + + _wemq_proxy_list_used = now_index; + if (_wemq_proxy_list[now_index].flag == 0) + { + _wemq_proxy_list[now_index].flag = 1; + } + + // 如果没有找到,由之前的使用默认IP调整为打印error日志,并等待黑名单解禁 + if (_wemq_proxy_list[now_index].failed_time != 0 && + (_wemq_proxy_list[now_index].failed_time + WEMQ_PROXY_SERVER_MAX_TIME) > + now_time) + { + pthread_mutex_unlock (&__wemq_proxy_rmutex); + LOGRMB (RMB_LOG_ERROR, "local proxy list all in black list"); + //*port = pRmbStConfig->cWemqProxyPort; + //snprintf(host, size, "%s", pRmbStConfig->cWemqProxyIp); + *port = 0; + memset (host, 0x00, sizeof (char) * size); + return 2; + } + + *port = (int) _wemq_proxy_list[now_index].port; + snprintf (host, size, "%s", _wemq_proxy_list[now_index].host); + pthread_mutex_unlock (&__wemq_proxy_rmutex); + + return 0; +} + +void wemq_proxy_goodbye (const char *host, unsigned int port) +{ + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return; + } + + struct timeval tv; + gettimeofday (&tv, NULL); +// long now_time = time(NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + + LOGRMB (RMB_LOG_INFO, + "[used: host,%s|port,%u] [wemq_proxy_list_used:%d] wemq_proxy_goodbye!\n", + host, port, _wemq_proxy_list_used); + pthread_mutex_lock (&__wemq_proxy_rmutex); + + int i = 0; + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if ((strcmp (host, _wemq_proxy_list[i].host) == 0) + && (port == _wemq_proxy_list[i].port)) + { +// LOGRMB(RMB_LOG_WARN, "[used: host:%s|port:%d] wemq_proxy_goodbye inconformity!", host, port); + atomic_set (&_wemq_proxy_list[i].failed_time, now_time); + } + } + pthread_mutex_unlock (&__wemq_proxy_rmutex); +} + +void wemq_proxy_to_black_list (const char *host, unsigned int port) +{ + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return; + } + + struct timeval tv; + gettimeofday (&tv, NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + + LOGRMB (RMB_LOG_INFO, "[host:%s|port:%u] add to black list!\n", host, port); + pthread_mutex_lock (&__wemq_proxy_rmutex); + int i = 0; + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if ((strcmp (host, _wemq_proxy_list[i].host) == 0) + && (port == _wemq_proxy_list[i].port)) + { + atomic_set (&_wemq_proxy_list[i].failed_time, now_time); + } + } + pthread_mutex_unlock (&__wemq_proxy_rmutex); +} + +void wemq_proxy_get_usable_server_list (int *wemq_proxy_usable_server_list, + int *wemq_proxy_usable_sever_weight, + int *wemq_proxy_usable_count) +{ + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return; + } + int i = 0; + int j = 0; + int loop = 0; + int local_idc_usable_flag = 0; + int wemq_proxy_usable_server_list_backup[_wemq_proxy_list_num]; + memset (wemq_proxy_usable_server_list_backup, 0x00, + sizeof (int) * _wemq_proxy_list_num); + int wemq_proxy_usable_count_backup = 0; + int wemq_proxy_usable_sever_weight_backup = 0; + bool usableLocalIdc = false; + + struct timeval tv; + gettimeofday (&tv, NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + + for (; i < _wemq_proxy_list_num; i++) + { + char isBlack = + ((_wemq_proxy_list[i].failed_time + WEMQ_PROXY_SERVER_MAX_TIME) <= + now_time) ? 'n' : 'y'; + //LOGRMB(RMB_LOG_DEBUG, "[host:%s, port:%d, black:%c]", _wemq_proxy_list[i].host, _wemq_proxy_list[i].port, isBlack); + if (strcmp (_wemq_proxy_list[i].idc, pRmbStConfig->cRegion) == 0) + { + + if (_wemq_proxy_list[i].failed_time == 0 + || (_wemq_proxy_list[i].failed_time + WEMQ_PROXY_SERVER_MAX_TIME) <= + now_time) + { + wemq_proxy_usable_server_list[j] = i; + j++; + *wemq_proxy_usable_count += 1; + *wemq_proxy_usable_sever_weight += (int) _wemq_proxy_list[i].weight; + usableLocalIdc = true; + //LOGRMB(RMB_LOG_DEBUG, "[host:%s | port:%u | weight:%d | index: %d] is usable!\n", _wemq_proxy_list[i].host, _wemq_proxy_list[i].port, _wemq_proxy_list[i].weight, i); + //LOGRMB(RMB_LOG_DEBUG, "j: %d | count: %d | weight: %d", j, *wemq_proxy_usable_count, *wemq_proxy_usable_sever_weight); + } + } + else + { + if (_wemq_proxy_list[i].failed_time == 0 + || (_wemq_proxy_list[i].failed_time + WEMQ_PROXY_SERVER_MAX_TIME) <= + now_time) + { + wemq_proxy_usable_server_list_backup[loop] = i; + loop++; + wemq_proxy_usable_count_backup += 1; + wemq_proxy_usable_sever_weight_backup += + (int) _wemq_proxy_list[i].weight; + //LOGRMB(RMB_LOG_DEBUG, "[host:%s | port:%u | weight:%d | index: %d] is usable!\n", _wemq_proxy_list[i].host, _wemq_proxy_list[i].port, _wemq_proxy_list[i].weight, i); + //LOGRMB(RMB_LOG_DEBUG, "j: %d | count: %d | weight: %d", j, *wemq_proxy_usable_count, *wemq_proxy_usable_sever_weight); + } + } + } + /* + for(i = 0; i < *wemq_proxy_usable_count; i++){ + LOGRMB(RMB_LOG_DEBUG, "[local usable index: %d]\n", wemq_proxy_usable_server_list[i]); + } + for(i = 0; i < wemq_proxy_usable_count_backup; i++){ + LOGRMB(RMB_LOG_DEBUG, "[backup usable index: %d]\n", wemq_proxy_usable_server_list_backup[i]); + } */ + + if (!usableLocalIdc) + { + memset (wemq_proxy_usable_server_list, 0, + sizeof (int) * _wemq_proxy_list_num); + memcpy (wemq_proxy_usable_server_list, + wemq_proxy_usable_server_list_backup, + sizeof (int) * wemq_proxy_usable_count_backup); + *wemq_proxy_usable_count = wemq_proxy_usable_count_backup; + *wemq_proxy_usable_sever_weight = wemq_proxy_usable_sever_weight_backup; + } + /* + for(i = 0; i < *wemq_proxy_usable_count; i++){ + LOGRMB(RMB_LOG_DEBUG, "[final usable index: %d]\n", wemq_proxy_usable_server_list[i]); + } + */ +} + +/** + * 判断所有的ip是否均连接过 + */ +int wemq_proxy_ip_is_connected () +{ + if (pRmbStConfig->iWemqUseHttpCfg != 1) + { + return 1; + } + + int iRet = 0; + int i = 0; + pthread_mutex_lock (&__wemq_proxy_rmutex); + for (i = 0; i < _wemq_proxy_list_num; i++) + { + if (_wemq_proxy_list[i].flag == 0) + break; + } + pthread_mutex_unlock (&__wemq_proxy_rmutex); + + if (i >= _wemq_proxy_list_num) + { + iRet = 1; + } + + return iRet; +} + +/** + * 分隔IP列表 + */ +void split_str (char *ips, char ipArray[][50], int *len) +{ + // printf("%s\n", ips); + //char (*ipArray)[50] = (char(*)[50])malloc(sizeof(char) * 15 * 50); + int count = 0; + char *ip = NULL; + ip = strtok (ips, ";"); + if (ip == NULL) + { + *len = 0; + return; + } + strcpy (ipArray[count], ip); + count++; + while (ip = strtok (NULL, ";")) + { + strcpy (ipArray[count], ip); + count++; + } + *len = count; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_cfg.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_cfg.c new file mode 100644 index 0000000000..15b9fdc0ed --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_cfg.c @@ -0,0 +1,594 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include "rmb_log.h" +#include "rmb_udp.h" +#include "rmb_cfg.h" +#include +#include +#include +#include + +#include "rmb_access_config.h" + +StRmbConfig *pRmbStConfig; + +int rmb_reload_config (); + +static char *rmb_get_val (char *desc, char *src) +{ + char *descp = desc, *srcp = src; + int mtime = 0, space = 0; + + while (mtime != 2 && *srcp != '\0') + { + switch (*srcp) + { + case ' ': + case '\t': + case '\0': + case '\n': + case US: + space = 1; + srcp++; + break; + default: + if (space || srcp == src) + mtime++; + space = 0; + if (mtime == 2) + break; + *descp = *srcp; + descp++; + srcp++; + } + } + *descp = '\0'; + strcpy (src, srcp); + return desc; +} + +static void rmb_InitDefault (va_list ap) +{ + char *sParam, *sVal, *sDefault; + double *pdVal, dDefault; + long *plVal, lDefault; + int iType, *piVal, iDefault; + long lSize; + short *pwVal = NULL; + short wDefault; + + sParam = va_arg (ap, char *); + + while (sParam != NULL) + { + iType = va_arg (ap, int); + + switch (iType) + { + case CFG_LINE: + sVal = va_arg (ap, char *); + sDefault = va_arg (ap, char *); + lSize = va_arg (ap, long); + + strncpy (sVal, sDefault, (int) lSize - 1); + sVal[lSize - 1] = 0; + //snprintf(sVal,lSize,"%s",sDefault); + break; + case CFG_STRING: + sVal = va_arg (ap, char *); + sDefault = va_arg (ap, char *); + lSize = va_arg (ap, long); + + strncpy (sVal, sDefault, (int) lSize - 1); + sVal[lSize - 1] = 0; + //snprintf(sVal,lSize,"%s",sDefault); + break; + case CFG_LONG: + plVal = va_arg (ap, long *); + lDefault = va_arg (ap, long); + + *plVal = lDefault; + break; + case CFG_INT: + piVal = va_arg (ap, int *); + iDefault = va_arg (ap, int); + + *piVal = iDefault; + break; + case CFG_SHORT: + pwVal = va_arg (ap, short *); + wDefault = va_arg (ap, int); + *pwVal = wDefault; + break; + case CFG_DOUBLE: + pdVal = va_arg (ap, double *); + dDefault = va_arg (ap, double); + + *pdVal = dDefault; + break; + } + sParam = va_arg (ap, char *); + } +} + +static void rmb_SetVal (va_list ap, const char *sP, char *sV) +{ + char *sParam = NULL, *sVal = NULL, *sDefault = NULL; + double *pdVal = NULL, dDefault; + long *plVal = NULL, lDefault; + int iType, *piVal = NULL, iDefault; + long lSize = 0; + char sLine[MAX_CONFIG_LINE_LEN + 1], sLine1[MAX_CONFIG_LINE_LEN + 1]; + short *pwVal = NULL; + short wDefault; + + strcpy (sLine, sV); + strcpy (sLine1, sV); + rmb_get_val (sV, sLine1); + sParam = va_arg (ap, char *); + + while (sParam != NULL) + { + iType = va_arg (ap, int); + + switch (iType) + { + case CFG_LINE: + sVal = va_arg (ap, char *); + sDefault = va_arg (ap, char *); + lSize = va_arg (ap, long); + + if (strcmp (sP, sParam) == 0) + { + strncpy (sVal, sLine, (int) lSize - 1); + sVal[lSize - 1] = 0; + //snprintf(sVal,lSize,"%s",sLine); + } + break; + case CFG_STRING: + sVal = va_arg (ap, char *); + sDefault = va_arg (ap, char *); + lSize = va_arg (ap, long); + + break; + case CFG_LONG: + plVal = va_arg (ap, long *); + lDefault = va_arg (ap, long); + + /* + if (strcmp(sP, sParam) == 0) + { + *plVal = atol(sV); + } + */ + break; + case CFG_INT: + piVal = va_arg (ap, int *); + iDefault = va_arg (ap, int); + + /* + if (strcmp(sP, sParam) == 0) + { + *piVal = iDefault; + } + */ + break; + case CFG_SHORT: + pwVal = va_arg (ap, short *); + wDefault = va_arg (ap, int); + break; + case CFG_DOUBLE: + pdVal = va_arg (ap, double *); + dDefault = va_arg (ap, double); + + *pdVal = dDefault; + break; + } + + if (strcmp (sP, sParam) == 0) + { + switch (iType) + { + case CFG_STRING: + strncpy (sVal, sV, (int) lSize - 1); + sVal[lSize - 1] = 0; + break; + case CFG_LONG: + //*plVal = atol(sV); + *plVal = strtoul (sV, NULL, 0); + break; + case CFG_INT: + //*piVal = atoi(sV); + *piVal = strtoul (sV, NULL, 0); + break; + case CFG_SHORT: + *pwVal = strtoul (sV, NULL, 0); + break; + case CFG_DOUBLE: + *pdVal = atof (sV); + break; + } + + return; + } + + sParam = va_arg (ap, char *); + } +} + +static int rmb_GetParamVal (char *sLine, char *sParam, char *sVal) +{ + + rmb_get_val (sParam, sLine); + strcpy (sVal, sLine); + + if (sParam[0] == '#') + return 1; + + return 0; +} + +void RMB_TLib_Cfg_GetConfig (char *sConfigFilePath, ...) +{ + FILE *pstFile; + char sLine[MAX_CONFIG_LINE_LEN + 1], sParam[MAX_CONFIG_LINE_LEN + 1], + sVal[MAX_CONFIG_LINE_LEN + 1]; + va_list ap; + char *pCur = NULL; + + va_start (ap, sConfigFilePath); + rmb_InitDefault (ap); + va_end (ap); + + if ((pstFile = fopen (sConfigFilePath, "r")) == NULL) + { + // printf("Can't open Config file '%s', ignore.", sConfigFilePath); + return; + } + + while (1) + { + pCur = fgets (sLine, sizeof (sLine), pstFile); + if (pCur == NULL) + break; + + if (feof (pstFile)) + { + break; + } + + if (rmb_GetParamVal (sLine, sParam, sVal) == 0) + { + va_start (ap, sConfigFilePath); + rmb_SetVal (ap, sParam, sVal); + va_end (ap); + } + } + + fclose (pstFile); +} + +void rmb_cfg_process_signal (int sigalNo) +{ + switch (sigalNo) + { + case SIGUSR1: + { + LOGRMB (RMB_LOG_INFO, "pid=%u receive user signal 1,reload cfg!", + pRmbStConfig->uiPid); + rmb_reload_config (); + LOGRMB (RMB_LOG_INFO, "pid=%u reload cfg succ!", pRmbStConfig->uiPid); + break; + } + case SIGUSR2: + { + LOGRMB (RMB_LOG_INFO, "pid=%u receive user signal 2,reload cfg!", + pRmbStConfig->uiPid); + rmb_reload_config (); + LOGRMB (RMB_LOG_INFO, "pid=%u reload cfg succ!", pRmbStConfig->uiPid); + break; + } + default: + { + printf ("receive signal=%u", sigalNo); + } + } + return; +} + +int rmb_reload_config () +{ + Rmb_TLib_Cfg_GetConfig (pRmbStConfig->strConfigFile, + "consumerSysId", CFG_STRING, + pRmbStConfig->cConsumerSysId, "", + sizeof (pRmbStConfig->cConsumerSysId), + "consumerSysVersion", CFG_STRING, + pRmbStConfig->cConsumerSysVersion, "", + sizeof (pRmbStConfig->cConsumerSysVersion), + "consumerDcn", CFG_STRING, + pRmbStConfig->cConsumerDcn, "", + sizeof (pRmbStConfig->cConsumerDcn), "logFile", + CFG_STRING, pRmbStConfig->logFileName, "../rmb/log", + sizeof (pRmbStConfig->logFileName), "logLevel", + CFG_INT, &(pRmbStConfig->iLogLevel), 5, + "logFileNums", CFG_INT, + &(pRmbStConfig->iLogFileNums), 100, "logFileSize", + CFG_INT, &(pRmbStConfig->iLogFileSize), 500000000, + "logSwiftType", CFG_INT, + &(pRmbStConfig->iLogShiftType), 1, "debugSwitch", + CFG_INT, &(pRmbStConfig->iDebugSwitch), 0, + "everyProcessNumFromMq", CFG_INT, + &(pRmbStConfig->iEveryTimeProcessNum), 10, + "notifyCheckSpan", CFG_INT, + &(pRmbStConfig->iNotifyCheckSpan), 1, + "notifyMergeSwitch", CFG_INT, + &(pRmbStConfig->iFLagForMergeNotify), 1, "orgId", + CFG_STRING, pRmbStConfig->strOrgId, "99996", + sizeof (pRmbStConfig->strOrgId), "cacheTimeout", + CFG_INT, &(pRmbStConfig->iCacheTimeoutTime), 10, + "cacheSuccTimeout", CFG_INT, + &(pRmbStConfig->iCacheSuccTimeoutTime), 600, + "cacheFailedTimeout", CFG_INT, + &(pRmbStConfig->iCacheFailedTimeoutTime), 30, + "switchForReloadSignal1", CFG_INT, + &(pRmbStConfig->iSwitchForSignal1), 1, + "switchForReloadSignal2", CFG_INT, + &(pRmbStConfig->iSwitchForSignal2), 0, "ackTimer", + CFG_INT, &(pRmbStConfig->ackTimers), 100, + "ackThreshold", CFG_INT, + &(pRmbStConfig->ackThresHold), 30, "queryTimeout", + CFG_INT, &(pRmbStConfig->iQueryTimeout), 1000, + "CommonTimeOut", CFG_INT, + &(pRmbStConfig->iCommonTimeOut), 500, "StatPeriod", + CFG_INT, &(pRmbStConfig->iStatPeriod), 300, + "GetGroupTopicTime", CFG_INT, + &(pRmbStConfig->iGetGroupTopicTime), 5, + "GetSendWhiteListTime", CFG_INT, + &(pRmbStConfig->iGetSendWhiteListTime), 30, NULL); + + //ackTimer的范围为20到1500 + if (pRmbStConfig->ackTimers > 1500) + pRmbStConfig->ackTimers = 1500; + if (pRmbStConfig->ackTimers < 20) + pRmbStConfig->ackTimers = 20; + + //ackThreshold的范围为1 到75 + if (pRmbStConfig->ackThresHold > 75) + pRmbStConfig->ackThresHold = 75; + if (pRmbStConfig->ackThresHold < 1) + pRmbStConfig->ackThresHold = 1; + + if (pRmbStConfig->iQueryTimeout > 5000) + pRmbStConfig->iQueryTimeout = 5000; + if (pRmbStConfig->iQueryTimeout < 500) + pRmbStConfig->iQueryTimeout = 500; + + if (pRmbStConfig->iSwitchForSignal1) + { + signal (SIGUSR1, rmb_cfg_process_signal); + } + + if (pRmbStConfig->iSwitchForSignal2) + { + signal (SIGUSR2, rmb_cfg_process_signal); + } + + return 0; +} + +int rmb_load_config (const char *configPath) +{ + pRmbStConfig = (StRmbConfig *) calloc (1, sizeof (StRmbConfig)); + if (pRmbStConfig == NULL) + { + printf ("rmb_load_config pRmbStConfig calloc error!"); + return -1; + } + + init_error (); + snprintf (pRmbStConfig->strConfigFile, + sizeof (pRmbStConfig->strConfigFile) - 1, "%s", configPath); + Rmb_TLib_Cfg_GetConfig (pRmbStConfig->strConfigFile, "consumerSysId", CFG_STRING, pRmbStConfig->cConsumerSysId, "", sizeof (pRmbStConfig->cConsumerSysId), "consumerSysVersion", CFG_STRING, pRmbStConfig->cConsumerSysVersion, "1.0.0", sizeof (pRmbStConfig->cConsumerSysVersion), "consumerDcn", CFG_STRING, pRmbStConfig->cConsumerDcn, "", sizeof (pRmbStConfig->cConsumerDcn), "logFile", CFG_STRING, pRmbStConfig->logFileName, "../log/rmb.log", sizeof (pRmbStConfig->logFileName), "logLevel", CFG_INT, &(pRmbStConfig->iLogLevel), 5, "logFileNums", CFG_INT, &(pRmbStConfig->iLogFileNums), 100, "logFileSize", CFG_INT, &(pRmbStConfig->iLogFileSize), 500000000, "logSwiftType", CFG_INT, &(pRmbStConfig->iLogShiftType), 1, "debugSwitch", CFG_INT, &(pRmbStConfig->iDebugSwitch), 0, "everyProcessNumFromMq", CFG_INT, &(pRmbStConfig->iEveryTimeProcessNum), 10, "notifyCheckSpan", CFG_INT, &(pRmbStConfig->iNotifyCheckSpan), 1, "notifyMergeSwitch", CFG_INT, &(pRmbStConfig->iFLagForMergeNotify), 1, "reqFifoPath", CFG_STRING, pRmbStConfig->strFifoPathForReq, "./tmp_req.fifo", sizeof (pRmbStConfig->strFifoPathForReq), "reqShmKey", CFG_INT, &(pRmbStConfig->uiShmKeyForReq), 0x20150203, "reqShmSize", CFG_INT, &(pRmbStConfig->uiShmSizeForReq), 200000000, "ayncRspFifoPath", CFG_STRING, pRmbStConfig->strFifoPathForRRrsp, "./tmp_aync_rsp.fifo", sizeof (pRmbStConfig->strFifoPathForReq), "ayncRspShmKey", CFG_INT, &(pRmbStConfig->uiShmKeyForRRrsp), 0x20150204, "ayncRspShmSize", CFG_INT, &(pRmbStConfig->uiShmSizeForRRrsp), 200000000, "broadcastFifoPath", CFG_STRING, pRmbStConfig->strFifoPathForBroadcast, "./tmp_broadcast.fifo", sizeof (pRmbStConfig->strFifoPathForReq), "broadcastShmKey", CFG_INT, &(pRmbStConfig->uiShmKeyForBroadcast), 0x20150205, "broadcastShmSize", CFG_INT, &(pRmbStConfig->uiShmSizeForBroadcast), 200000000, "orgId", CFG_STRING, pRmbStConfig->strOrgId, "99996", sizeof (pRmbStConfig->strOrgId), "cacheTimeout", CFG_INT, &(pRmbStConfig->iCacheTimeoutTime), 10, "cacheSuccTimeout", CFG_INT, &(pRmbStConfig->iCacheSuccTimeoutTime), 600, "cacheFailedTimeout", CFG_INT, &(pRmbStConfig->iCacheFailedTimeoutTime), 30, "createConnectionTimeOut", CFG_INT, &(pRmbStConfig->createConnectionTimeOut), 120, "switchForReloadSignal1", CFG_INT, &(pRmbStConfig->iSwitchForSignal1), 1, "switchForReloadSignal2", CFG_INT, &(pRmbStConfig->iSwitchForSignal2), 0, "ackTimer", CFG_INT, &(pRmbStConfig->ackTimers), 100, "ackThreshold", CFG_INT, &(pRmbStConfig->ackThresHold), 30, "queryTimeout", CFG_INT, &(pRmbStConfig->iQueryTimeout), 1000, "CommonTimeOut", CFG_INT, &(pRmbStConfig->iCommonTimeOut), 500, "StatPeriod", CFG_INT, &(pRmbStConfig->iStatPeriod), 300, "GetGroupTopicTime", CFG_INT, &(pRmbStConfig->iGetGroupTopicTime), 5, "logserverSwitch", CFG_INT, &(pRmbStConfig->iLogserverSwitch), 1, "logserverForApiSwitch", CFG_INT, &(pRmbStConfig->iApiLogserverSwitch), 1, "ReqGslSwitch", CFG_INT, &(pRmbStConfig->iReqGsl), 1, "wemqUseHttpCfg", CFG_INT, &(pRmbStConfig->iWemqUseHttpCfg), 1, "configCenterIp", CFG_STRING, pRmbStConfig->cConfigIp, "", sizeof (pRmbStConfig->cConfigIp), "configCenterPort", CFG_INT, &(pRmbStConfig->iConfigPort), 8091, "configCenterAddrMulti", CFG_STRING, pRmbStConfig->ConfigAddr, "", sizeof (pRmbStConfig->ConfigAddr), "configCenterTimeout", CFG_INT, &(pRmbStConfig->iConfigTimeout), 10000, "mergeQueueSwitch", CFG_INT, &(pRmbStConfig->iMergeQueue), 0, "tlsOnoff", CFG_INT, &(pRmbStConfig->tlsOnoff), 0, "wemq_user", CFG_STRING, pRmbStConfig->cWemqUser, "", sizeof (pRmbStConfig->cWemqUser), "wemq_passwd", CFG_STRING, pRmbStConfig->cWemqPasswd, "", sizeof (pRmbStConfig->cWemqPasswd), "localIdc", CFG_STRING, pRmbStConfig->cRegion, "", sizeof (pRmbStConfig->cRegion), "heartBeatPeriod", CFG_INT, &(pRmbStConfig->heartBeatPeriod), 30, "heartBeatTimeout", CFG_INT, &(pRmbStConfig->heartBeatTimeout), 45, "getAccessIpPeriod", CFG_INT, &(pRmbStConfig->getAccessIpPeriod), 30, "wemqTcpConnectRetryNum", CFG_INT, &(pRmbStConfig->iWemqTcpConnectRetryNum), 1, "wemqTcpConnectDelayTime", CFG_INT, &(pRmbStConfig->iWemqTcpConnectDelayTime), 5, "wemqTcpConnectTimeout", CFG_INT, &(pRmbStConfig->iWemqTcpConnectTimeout), 3000, "wemqTcpSocketTimeout", CFG_INT, &(pRmbStConfig->iWemqTcpSocketTimeout), 5000, "wemqProxyIp", CFG_STRING, pRmbStConfig->cWemqProxyIp, "", sizeof (pRmbStConfig->cWemqProxyIp), "wemqProxyPort", CFG_INT, &(pRmbStConfig->cWemqProxyPort), 50001, "normalTimeout", CFG_INT, &(pRmbStConfig->iNormalTimeout), 120000, "exitTimeOut", CFG_INT, &(pRmbStConfig->ulExitTimeOut), 30000, "getSendWhiteListTime", CFG_INT, &(pRmbStConfig->iGetSendWhiteListTime), 300, "accessAckTimeOut", CFG_INT, &(pRmbStConfig->accessAckTimeOut), 2000, "rrAsyncTimeOut", CFG_INT, &(pRmbStConfig->rrAsyncTimeOut), 3, //默认rr异步3秒超时 + "goodByeTimeOut", CFG_INT, &(pRmbStConfig->goodByeTimeOut), 2000, //goodbye time 2s + //"rrAsyncListNum", CFG_INT, &(pRmbStConfig->accessAckTimeOut),10240, + "mqIsEmpty", CFG_INT, &(pRmbStConfig->mqIsEmpty), + MQ_INIT, "departMent", CFG_STRING, + pRmbStConfig->strDepartMent, "wemqAccessServer", + sizeof (pRmbStConfig->strDepartMent), NULL); + + pRmbStConfig->uiPid = getpid (); + snprintf (pRmbStConfig->cRmbMode, sizeof (pRmbStConfig->cRmbMode), "wemq"); + //initialize for log + InitRmbLogFile (pRmbStConfig->iLogLevel, pRmbStConfig->iLogShiftType, + pRmbStConfig->logFileName, pRmbStConfig->iLogFileSize, + pRmbStConfig->iLogFileNums); + //API CONNECT MODE + //connect to wemq + pRmbStConfig->iConnWemq = 1; + + //solace api 初始化,用于生成uuid + pRmbStConfig->uiIsInitSolaceApi = 0; + + int iRet = 0; + //从配置中心拉取access的ip list,如果配置为指定access的ip,则无须从配置中心拉取 + if ((pRmbStConfig->iWemqUseHttpCfg == 1) + && (pRmbStConfig->iConnWemq == 1 + || pRmbStConfig->iApiLogserverSwitch == 1)) + { + char url[512]; + char addrArr[15][50] = { 0 }; + int lenAddrs = 0; + pRmbStConfig->configIpPosInArr = 0; + char tmpIps[512] = { 0 }; + strcpy (tmpIps, pRmbStConfig->ConfigAddr); + LOGRMB (RMB_LOG_DEBUG, "config center addr str is:%s", tmpIps); + split_str (tmpIps, addrArr, &lenAddrs); + LOGRMB (RMB_LOG_DEBUG, "config center addr list len is %d,lists:", + lenAddrs); + int j = 0; + for (j = 0; j < lenAddrs; ++j) + { + LOGRMB (RMB_LOG_DEBUG, "%s", addrArr[j]); + } + + if (lenAddrs == 0) + { + LOGRMB (RMB_LOG_ERROR, + "config center addr list len is 0,please check if configCenterAddrMulti is empty in conf file"); + return -1; + } + int i = 0; + for (i = 0; i < lenAddrs; ++i) + { + memset (&url, 0x00, sizeof (url)); + snprintf (url, sizeof (url), "%s/%s", + addrArr[(i + pRmbStConfig->configIpPosInArr) % lenAddrs], + WEMQ_ACCESS_SERVER); + LOGRMB (RMB_LOG_DEBUG, "try to get access addr from %s", url); + iRet = wemq_proxy_load_servers (url, pRmbStConfig->iConfigTimeout); + if (iRet != 0) + { + LOGRMB (RMB_LOG_WARN, + "get access ip from %s failed,try next config center ip", + url); + continue; + } + else + { + LOGRMB (RMB_LOG_INFO, "get all access ip list result=%d from url:%s", + iRet, url); + pRmbStConfig->configIpPosInArr = pRmbStConfig->configIpPosInArr + i; + break; + } + } + if (i == lenAddrs) + { + LOGRMB (RMB_LOG_ERROR, " no available cc"); + return -1; + } + } + pRmbStConfig->iFlagForLoop = 0; + + //ackTimer的范围为20到1500 + if (pRmbStConfig->ackTimers > 1500) + pRmbStConfig->ackTimers = 1500; + if (pRmbStConfig->ackTimers < 20) + pRmbStConfig->ackTimers = 20; + + //ackThreshold的范围为1 到75 + if (pRmbStConfig->ackThresHold > 75) + pRmbStConfig->ackThresHold = 75; + if (pRmbStConfig->ackThresHold < 1) + pRmbStConfig->ackThresHold = 1; + + if (pRmbStConfig->iQueryTimeout > 5000) + pRmbStConfig->iQueryTimeout = 5000; + if (pRmbStConfig->iQueryTimeout < 500) + pRmbStConfig->iQueryTimeout = 500; + + pRmbStConfig->pLogBuf = NULL; + pRmbStConfig->pLogBuf = (char *) malloc ((size_t) MAX_LOG_BUF_SIZE); + if (pRmbStConfig->pLogBuf == NULL) + { + printf ("malloc for pRmbStConfig->pLogBuf error!"); + return -1; + } + + iRet = + get_host_name (pRmbStConfig->cHostName, sizeof (pRmbStConfig->cHostName)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, " get_host_name failed!"); + //exit(1); + } + +// iRet = get_local_ip(pRmbStConfig->cHostIp, sizeof(pRmbStConfig->cHostIp)); + iRet = + get_local_ip_v2 (pRmbStConfig->cHostIp, sizeof (pRmbStConfig->cHostIp)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "get_local_ip failed!"); + //exit(1); + } + + LOGRMB (RMB_LOG_INFO, "get_host_name hostname=%s,ip=%s", + pRmbStConfig->cHostName, pRmbStConfig->cHostIp); + + //init queue config + pthread_mutex_init (&pRmbStConfig->configMutex, NULL); + pthread_cond_init (&pRmbStConfig->configCond, NULL); + pRmbStConfig->iFlag = 0; + GetRmbNowLongTime (); + pRmbStConfig->ulStartTime = pRmbStConfig->ulNowTtime; + pRmbStConfig->iCacheServiceNums = 0; + + //init mergeq for gsl + pthread_mutex_init (&pRmbStConfig->mergeqForGslMutex, NULL); + pthread_cond_init (&pRmbStConfig->mergeqForGslCond, NULL); + pRmbStConfig->iFlagForMerge = 0; + + //init merge queue mutex + pthread_mutex_init (&pRmbStConfig->mergeQueueMutex, NULL); + + //init for log + pthread_mutex_init (&pRmbStConfig->configLog, NULL); + + //pthread_mutex_init(&pRmbStConfig->sendWhiteListMutex, NULL); + + if (pRmbStConfig->iSwitchForSignal1) + { + signal (SIGUSR1, rmb_cfg_process_signal); + } + + if (pRmbStConfig->iSwitchForSignal2) + { + signal (SIGUSR2, rmb_cfg_process_signal); + } + + pRmbStConfig->flag_merge = 0; + pRmbStConfig->pid_merge = 0; + + return 0; +} + +void rmb_get_config_python (RmbPythonConfig * config) +{ + //pythonConfig init + snprintf (config->strFifoPathForReq, sizeof (config->strFifoPathForReq), + pRmbStConfig->strFifoPathForReq); + config->uiShmKeyForReq = pRmbStConfig->uiShmKeyForReq; + config->uiShmSizeForReq = pRmbStConfig->uiShmSizeForReq; + snprintf (config->strFifoPathForRRrsp, sizeof (config->strFifoPathForRRrsp), + pRmbStConfig->strFifoPathForRRrsp); + config->uiShmKeyForRRrsp = pRmbStConfig->uiShmKeyForRRrsp; + config->uiShmSizeForRRrsp = pRmbStConfig->uiShmSizeForRRrsp; + + snprintf (config->strFifoPathForBroadcast, + sizeof (config->strFifoPathForBroadcast), + pRmbStConfig->strFifoPathForBroadcast); + config->uiShmKeyForBroadcast = pRmbStConfig->uiShmKeyForBroadcast; + config->uiShmSizeForBroadcast = pRmbStConfig->uiShmSizeForBroadcast; + return; +} + +const char *rmb_get_host_ip () +{ + return pRmbStConfig->cHostIp; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_context.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_context.c new file mode 100644 index 0000000000..b8ad1c9e1f --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_context.c @@ -0,0 +1,907 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "rmb_context.h" +#include "rmb_udp.h" +#include "rmb_log.h" +#include "rmb_common.h" +#include "rmb_msg.h" +#include "rmb_mq.h" +#include "rmb_errno.h" +#include +#include +#include "wemq_thread.h" + +//char cManageTopic[30] = "rmb_c/manage"; +char cManageTopic[30] = "rmb_c_api/manage"; +char cQueueFullTopic[30] = "VPN_AD_MSG_SPOOL_TOPIC"; +char cLogLevelTopic[30] = "OPEN_DEBUG_LOG_TOPIC"; +char cPublishCheck[30] = "ALLOW_PUBLISH_MESSAGE_TOPIC"; +#define TWO_STOP_TIME 300000 + +//add for period log thread +int g_iLogThreadInit = 0; +pthread_t g_stLogThreadId; + +//////////////for wemq +static void _wemq_worker_thread_func (void *arg) +{ + StThreadArgs *pArg = (StThreadArgs *) arg; + WemqThreadCtx stThreadCtx; + stThreadCtx.m_ptProxyContext = pArg->pStContextProxy; + stThreadCtx.m_contextType = pArg->contextType; + stThreadCtx.m_iState = THREAD_STATE_INIT; + + stThreadCtx.sslCtx = NULL; + stThreadCtx.m_iSockFd = -1; + stThreadCtx.ssl = NULL; + stThreadCtx.m_iSockFdNew = -1; + stThreadCtx.sslNew = NULL; + stThreadCtx.m_iSockFdOld = -1; + stThreadCtx.sslOld = NULL; + + if (pArg->contextType == RMB_CONTEXT_TYPE_PUB) + { + stThreadCtx.m_ptTopicList = NULL; + stThreadCtx.m_ptFifo = (void *) &(pArg->pStContextProxy->pubFifo); + } + else + { + stThreadCtx.m_ptTopicList = &(pArg->pStContextProxy->stTopicList); + stThreadCtx.m_ptFifo = (void *) &(pArg->pStContextProxy->subFifo); + } + + wemq_thread_run (&stThreadCtx); + free (pArg); +} + +static int _wemq_context_create_thread (int contextType, + stContextProxy * pContextProxy) +{ + int iRet = -1; + if (contextType == RMB_CONTEXT_TYPE_PUB) + { + //thread has been created + if (pContextProxy->mainThreadId != 0) + { + return 0; + } + + //create pub thread (main thread); + StThreadArgs *pMainArgs = (StThreadArgs *) malloc (sizeof (StThreadArgs)); + if (pMainArgs == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for pMainArgs failed!"); + return -1; + } + pMainArgs->pStContextProxy = pContextProxy; + pMainArgs->contextType = RMB_CONTEXT_TYPE_PUB; + + iRet = + pthread_create (&pContextProxy->mainThreadId, NULL, + (void *) &_wemq_worker_thread_func, pMainArgs); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "create main thread error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_CREATE_THREAD_FAIL; + return rmb_errno; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + pRmbStConfig->createConnectionTimeOut; + timeout.tv_nsec = nowTimeVal.tv_usec * 1000; + + pContextProxy->iFlagForPub = 0; + pthread_mutex_lock (&pContextProxy->pubMutex); + if (pContextProxy->iFlagForPub == 0) + { + pthread_cond_timedwait (&pContextProxy->pubCond, + &pContextProxy->pubMutex, &timeout); + } + pthread_mutex_unlock (&pContextProxy->pubMutex); + if (pContextProxy->iFlagForPub != 1) + { + return -1; + } + } + else if (contextType == RMB_CONTEXT_TYPE_SUB) + { + //thread has been created + if (pContextProxy->coThreadId != 0) + { + return 0; + } + + //create sub thread (co thread) + StThreadArgs *pCoArgs = (StThreadArgs *) malloc (sizeof (StThreadArgs)); + if (pCoArgs == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for pCoArgs failed!"); + return -2; + } + pCoArgs->pStContextProxy = pContextProxy; + pCoArgs->contextType = RMB_CONTEXT_TYPE_SUB; + iRet = + pthread_create (&pContextProxy->coThreadId, NULL, + (void *) &_wemq_worker_thread_func, pCoArgs); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "create co thread error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_CREATE_THREAD_FAIL; + return rmb_errno; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + pRmbStConfig->createConnectionTimeOut; + timeout.tv_nsec = nowTimeVal.tv_usec * 1000; + + pContextProxy->iFlagForSub = 0; + pthread_mutex_lock (&pContextProxy->subMutex); + if (pContextProxy->iFlagForSub == 0) + { + pthread_cond_timedwait (&pContextProxy->subCond, + &pContextProxy->subMutex, &timeout); + } + pthread_mutex_unlock (&pContextProxy->subMutex); + if (pContextProxy->iFlagForSub != 1) + { + return -1; + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "contextType is illegal(%d)!", contextType); + rmb_errno = RMB_ERROR_CREATE_THREAD_FAIL; + return rmb_errno; + } +// sleep(1); //等待线程先执行 + return 0; +} + +static void wemq_context_init_thread_sync_obj (stContextProxy * pContextProxy) +{ + pthread_mutex_init (&pContextProxy->rrMutex, NULL); + pthread_cond_init (&pContextProxy->rrCond, NULL); + pContextProxy->iFlagForRR = 0; + + pthread_mutex_init (&pContextProxy->regMutex, NULL); + pthread_cond_init (&pContextProxy->regCond, NULL); + pContextProxy->iFlagForReg = 0; + + pthread_mutex_init (&pContextProxy->pubMutex, NULL); + pthread_cond_init (&pContextProxy->pubCond, NULL); + pContextProxy->iFlagForPub = 0; + + pthread_mutex_init (&pContextProxy->subMutex, NULL); + pthread_cond_init (&pContextProxy->subCond, NULL); + pContextProxy->iFlagForSub = 0; + + pthread_mutex_init (&pContextProxy->eventMutex, NULL); + pthread_cond_init (&pContextProxy->eventCond, NULL); + pContextProxy->iFlagForEvent = 0; //初始值设置为0,发送时设为-1,发送完ack再设为0。确保所有消息都回来的时候为0.相当于初始状态 + pContextProxy->iFlagForRRAsync = 0; + +} + +int wemq_context_init_add_manage_topic (stContextProxy * pContextProxy, + int type) +{ + int iRet = -1; + StWemqThreadMsg stThreadMsg; + stThreadMsg.m_iCmd = THREAD_MSG_CMD_ADD_MANAGE; + + if (type == 1) + { + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "send msg to worker thread by kfifo error\n"); + } + } + else + { + iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "send msg to worker thread by kfifo error\n"); + } + } + + struct timeval nowTimeVal; + struct timespec timeout; + gettimeofday (&nowTimeVal, NULL); + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForReg = 0; + pthread_mutex_lock (&pContextProxy->regMutex); + if (pContextProxy->iFlagForReg == 0) + { + pthread_cond_timedwait (&pContextProxy->regCond, &pContextProxy->regMutex, + &timeout); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + + if (pContextProxy->iFlagForReg != 1) + { + LOGRMB (RMB_LOG_ERROR, "add manage topic timeout!\n"); + rmb_errno = RMB_ERROR_WORKER_REGISTER_ERROR; + return rmb_errno; + } + + /* + if (pContextProxy->rspForAddManage.uiResult != 0) + { + LOGWEMQ(WEMQ_LOG_ERROR, "Failed to add magnage!manageTopic=%s\n", pContextProxy->rspForAddManage.strManageTopic); + return -1; + } + */ + return 0; +} + +static int wemq_context_init_proxy_model (StContext * pStContext) +{ + stContextProxy *pContextProxy = NULL; + + //context proxy has been init; + //get only one contextproxy; + if (pRmbStConfig->iProxyContextNums == 1) + { + pStContext->pContextProxy = pRmbStConfig->pProxyContext; + pContextProxy = pRmbStConfig->pProxyContext; + if (pStContext->contextType == RMB_CONTEXT_TYPE_PUB) + { + pContextProxy->pubContext = (void *) pStContext; + } + else + { + pContextProxy->subContext = (void *) pStContext; + } + + return _wemq_context_create_thread (pStContext->contextType, + pContextProxy); + } + + //create proxy context + pContextProxy = (stContextProxy *) malloc (sizeof (stContextProxy)); + if (pContextProxy == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStContext->pContextProxy malloc error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + memset (pContextProxy, 0, sizeof (stContextProxy)); + pContextProxy->iFlagForRun = 1; + pContextProxy->ulGoodByeTime = 0; + pContextProxy->ulLastClearRRAysncMsgTime = 0; + + pStContext->pContextProxy = pContextProxy; + + if (pStContext->contextType == RMB_CONTEXT_TYPE_PUB) + { + pContextProxy->pubContext = (void *) pStContext; + } + else + { + pContextProxy->subContext = (void *) pStContext; + } + + INIT_WEMQ_KFIFO (pContextProxy->pubFifo); + INIT_WEMQ_KFIFO (pContextProxy->subFifo); + + wemq_topic_list_init (&pContextProxy->stTopicList); + + wemq_context_init_thread_sync_obj (pContextProxy); + +// pContextProxy->rrHashTable = (myhast_t *)malloc(sizeof(myhash_t)); +// if (pContextProxy->rrHashTable == NULL || +// myhash_init(pContextProxy->rrHashTable, 10000000)) +// { +// LOGRMB(RMB_LOG_ERROR, "pContextProxy->rrHashTable malloc or init error!\n"); +// rmb_errno = RMB_ERROR_MALLOC_FAIL; +// return rmb_errno; +// } + + pContextProxy->pReplyMsg = rmb_msg_malloc (); + + //all buffer initialize + pContextProxy->mPubRRBuf = (char *) malloc (TCP_BUF_SIZE * sizeof (char)); + if (pContextProxy->mPubRRBuf == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy->mPubRRBuf malloc error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + memset (pContextProxy->mPubRRBuf, 0x00, TCP_BUF_SIZE * sizeof (char)); + + Init (&pContextProxy->pUniqueListForRRAsyncNew); + Init (&pContextProxy->pUniqueListForRRAsyncOld); + + //pContextProxy->pUniqueListForRRAsyncNew = pContextProxy->stUniqueListForRRAsync; + //pContextProxy->pUniqueListForRRAsyncOld = pContextProxy->stUniqueListForRRAsyncOld; + //memset(pContextProxy->pUniqueListForRRAsyncNew,0x00,RMB_MAX_UNIQUE_NUMS * sizeof(StUniqueIdList)); + //memset(pContextProxy->pUniqueListForRRAsyncOld,0x00,RMB_MAX_UNIQUE_NUMS * sizeof(StUniqueIdList)); + + // context proxy init ok; + pRmbStConfig->pProxyContext = pContextProxy; + pRmbStConfig->iProxyContextNums = 1; + + return _wemq_context_create_thread (pStContext->contextType, pContextProxy); +} + +StContext *g_pStContextArry[MAX_RMB_CONTEXT] = { NULL }; + +int Log_Thread_Start (StContext * pStContext) +{ + LOGRMB (RMB_LOG_INFO, "call thread start StContext = 0x%p", pStContext); + + if (pStContext->contextType == RMB_CONTEXT_TYPE_PUB) + { + pRmbStConfig->iFlagForLoop = 1; + } + + pthread_mutex_lock (&pRmbStConfig->configLog); + if (g_iLogThreadInit == 1) + { + if (g_pStContextArry[1] == NULL) + g_pStContextArry[1] = pStContext; + pthread_mutex_unlock (&pRmbStConfig->configLog); + return 0; + } + + g_iLogThreadInit = 1; + pthread_mutex_unlock (&pRmbStConfig->configLog); + + g_pStContextArry[0] = pStContext; + g_pStContextArry[1] = NULL; + + int iRet = + pthread_create (&g_stLogThreadId, NULL, (void *) &_Log_Thread_func, NULL); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "create Log thread error!iRet=%d\n", iRet); + } + return iRet; +} + +int rmb_context_init (StContext * pStContext) +{ + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStContext is null!"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + if (pStContext->uiInitFlag == 1) + { + LOGRMB (RMB_LOG_ERROR, "pStContext has already init!"); + return 0; + } + + int iRet = 0; + + pStContext->pReceiveWemqMsg = NULL; + pStContext->pReceiveWemqMsg = rmb_msg_malloc (); + if (pStContext->pReceiveWemqMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for pStContext->pReceiveWemqMsg error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + + pStContext->pReceiveWemqMsgForRR = NULL; + pStContext->pReceiveWemqMsgForRR = rmb_msg_malloc (); + if (pStContext->pReceiveWemqMsgForRR == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "malloc for pStContext->pReceiveWemqMsgForRR error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + + pStContext->pReceiveWemqMsgForBroadCast = NULL; + pStContext->pReceiveWemqMsgForBroadCast = rmb_msg_malloc (); + if (pStContext->pReceiveWemqMsgForBroadCast == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "malloc for pStContext->pReceiveWemqMsgForBroadCast failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + + pStContext->pWemqPkg = NULL; + pStContext->pWemqPkg = (char *) malloc (MAX_LENTH_IN_A_MSG); + if (pStContext->pWemqPkg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for pStContext->pWemqPkg error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + memset (pStContext->pWemqPkg, 0x00, MAX_LENTH_IN_A_MSG); + + pStContext->pWemqPkgForRRAsync = NULL; + pStContext->pWemqPkgForRRAsync = (char *) malloc (MAX_LENTH_IN_A_MSG); + if (pStContext->pWemqPkgForRRAsync == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "malloc for pStContext->pWemqPkgForRRAsync error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + memset (pStContext->pWemqPkgForRRAsync, 0x00, MAX_LENTH_IN_A_MSG); + + pStContext->uiInitFlag = 1; +// int iRet = Log_Thread_Start(pStContext); + iRet = wemq_context_init_proxy_model (pStContext); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_context_init_proxy_model failed, iRet=%d", + iRet); + return iRet; + } + + iRet = Log_Thread_Start (pStContext); + + return 0; +} + +int rmb_context_add_rsp_socket (StContext * pStContext, const char *cLocalIp, + unsigned short usRspPort) +{ + if (usRspPort != 0) + { + //init udp + pStContext->iSocketForRsp = udp_get_socket ("0.0.0.0", "0", NULL); + if (pStContext->iSocketForRsp < 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of udp socket init failed!port=%u", + (unsigned int) usRspPort); + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return -3; + } + tcp_nodelay (pStContext->iSocketForRsp); + bzero (&pStContext->tmpReplyAddr, sizeof (pStContext->tmpReplyAddr)); + pStContext->tmpReplyAddr.sin_addr.s_addr = inet_addr (cLocalIp); + pStContext->tmpReplyAddr.sin_port = htons (usRspPort); + pRmbStConfig->iFlagForRRrsp = (int) MSG_IPC_UDP; + } + else + { + pStContext->iSocketForRsp = 0; + } + return 0; +} + +int rmb_context_add_broadcast_socket (StContext * pStContext, + const char *cLocalIp, + unsigned short usBroadcastPort) +{ + if (usBroadcastPort != 0) + { + //init udp + pStContext->iSocketForBroadcast = udp_get_socket ("0.0.0.0", "0", NULL); + if (pStContext->iSocketForBroadcast < 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of udp socket init failed!port=%u", + (unsigned int) usBroadcastPort); + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return -3; + } + tcp_nodelay (pStContext->iSocketForBroadcast); + bzero (&pStContext->tmpBroadcastAddr, + sizeof (pStContext->tmpBroadcastAddr)); + pStContext->tmpBroadcastAddr.sin_addr.s_addr = inet_addr (cLocalIp); + pStContext->tmpBroadcastAddr.sin_port = htons (usBroadcastPort); + pRmbStConfig->iFlagForBroadCast = (int) MSG_IPC_UDP; + } + else + { + pStContext->iSocketForBroadcast = 0; + } + return 0; +} + +int rmb_context_add_req_socket (StContext * pStContext, const char *cLocalIp, + unsigned short usReqPort) +{ + if (usReqPort != 0) + { + //init udp + pStContext->iSocketForReq = udp_get_socket ("0.0.0.0", "0", NULL); + if (pStContext->iSocketForReq < 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of udp socket init failed!port=%u", + (unsigned int) usReqPort); + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return -3; + } + tcp_nodelay (pStContext->iSocketForReq); + bzero (&pStContext->tmpReqAddr, sizeof (pStContext->tmpReqAddr)); + //pStContext->tmpReqAddr.sin_family = AF_INET; + pStContext->tmpReqAddr.sin_addr.s_addr = inet_addr (cLocalIp); + pStContext->tmpReqAddr.sin_port = htons (usReqPort); + + if (pRmbStConfig->iDebugSwitch) + { + LOGRMB (RMB_LOG_DEBUG, "add_req,socket=%u,ip=%s,port=%u", + pStContext->iSocketForReq, cLocalIp, usReqPort); + } + pRmbStConfig->iFlagForReq = (int) MSG_IPC_UDP; + } + else + { + pStContext->iSocketForReq = 0; + } + return 0; +} + +int rmb_context_add_req_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv) +{ + int iRet = 0; + if (strlen (strFiFoPath) == 0) + { + LOGRMB (RMB_LOG_ERROR, "context_add_req_mq error!strFiFoPath size=0!"); + rmb_errno = RMB_ERROR_FIFO_PARA_ERROR; + return -1; + } + if (uiShmKey == 0 || uiShmSize == 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_req_mq error!shmKey=%u,shmSize=%u,fifoPath=%s", + uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_SHM_PARA_ERROR; + return -1; + } + //init mq + StRmbMq *pMq = (StRmbMq *) calloc (1, sizeof (StRmbMq)); + if (pMq == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of calloc mq failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + iRet = rmb_mq_init (pMq, uiShmKey, uiShmSize, true, false); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of rmb_mq_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_INIT_MQ_FAIL; + return -3; + } + + //init fifo + StRmbFifo *pFifo = (StRmbFifo *) calloc (1, sizeof (StRmbFifo)); + if (pFifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of calloc fifo failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -4; + } + iRet = rmb_fifo_init (pFifo, strFiFoPath); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of rmb_fifo_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pFifo); + free (pMq); + rmb_errno = RMB_ERROR_INIT_FIFO_FAIL; + return -5; + } + + iRet = + rmb_notify_add (&pStContext->fifoMq, pMq, pFifo, req_mq_index, func, + func_argv); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of rmb_notify_add failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + free (pFifo); + return -6; + } + LOGRMB (RMB_LOG_INFO, "context_add_req_mq succ!"); + pRmbStConfig->iFlagForReq = (int) MSG_IPC_MQ; + return 0; +} + +int rmb_context_add_rr_rsp_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv) +{ + int iRet = 0; + if (strlen (strFiFoPath) == 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!strFiFoPath size=0!"); + rmb_errno = RMB_ERROR_FIFO_PARA_ERROR; + return -1; + } + if (uiShmKey == 0 || uiShmSize == 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!shmKey=%u,shmSize=%u,fifoPath=%s", + uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_SHM_PARA_ERROR; + return -1; + } + //init mq + StRmbMq *pMq = (StRmbMq *) calloc (1, sizeof (StRmbMq)); + if (pMq == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!because of calloc mq failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + iRet = rmb_mq_init (pMq, uiShmKey, uiShmSize, true, false); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!because of rmb_mq_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_INIT_MQ_FAIL; + return -3; + } + + //init fifo + StRmbFifo *pFifo = (StRmbFifo *) calloc (1, sizeof (StRmbFifo)); + if (pFifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!because of calloc fifo failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -4; + } + iRet = rmb_fifo_init (pFifo, strFiFoPath); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo error!because of rmb_fifo_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pFifo); + free (pMq); + rmb_errno = RMB_ERROR_INIT_FIFO_FAIL; + return -5; + } + + iRet = + rmb_notify_add (&pStContext->fifoMq, pMq, pFifo, rr_rsp_mq_index, func, + func_argv); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context_add_rr_rsp_mq_fifo!because of rmb_notify_add failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + free (pFifo); + return -6; + } + pRmbStConfig->iFlagForRRrsp = (int) MSG_IPC_MQ; + return 0; +} + +int rmb_context_add_broadcast_mq_fifo (StContext * pStContext, + const char *strFiFoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + int iRet = 0; + if (strlen (strFiFoPath) == 0) + { + LOGRMB (RMB_LOG_ERROR, "fifo error!strFiFoPath size=0!"); + rmb_errno = RMB_ERROR_FIFO_PARA_ERROR; + return -1; + } + if (uiShmKey == 0 || uiShmSize == 0) + { + LOGRMB (RMB_LOG_ERROR, "shm error!shmKey=%u,shmSize=%u,fifoPath=%s", + uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_SHM_PARA_ERROR; + return -1; + } + //init mq + StRmbMq *pMq = (StRmbMq *) calloc (1, sizeof (StRmbMq)); + if (pMq == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmbMq error!because of calloc mq failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + iRet = rmb_mq_init (pMq, uiShmKey, uiShmSize, true, false); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "mq_init error!because of rmb_mq_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_INIT_MQ_FAIL; + return -3; + } + + //init fifo + StRmbFifo *pFifo = (StRmbFifo *) calloc (1, sizeof (StRmbFifo)); + if (pFifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "fifo null error!because of calloc fifo failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -4; + } + iRet = rmb_fifo_init (pFifo, strFiFoPath); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "fifo init error!because of rmb_fifo_init failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pFifo); + free (pMq); + rmb_errno = RMB_ERROR_INIT_FIFO_FAIL; + return -5; + } + + iRet = + rmb_notify_add (&pStContext->fifoMq, pMq, pFifo, broadcast_mq_index, func, + func_argv); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "notify add error!because of rmb_notify_add failed!iRet=%d,shmKey=%u,shmSize=%u,fifoPath=%s", + iRet, uiShmKey, uiShmSize, strFiFoPath); + free (pMq); + free (pFifo); + return -6; + } + LOGRMB (RMB_LOG_INFO, "context_add_broadcast_mq succ!"); + pRmbStConfig->iFlagForBroadCast = (int) MSG_IPC_MQ; + return 0; +} + +//////////////////////////////////////////////////////////////////////// +static int rmb_context_add_queue_pipe (StContext * pStContext, + const unsigned int uiSize, + const enum RmbMqIndex iMsgType, + rmb_callback_func func, + void *func_argv) +{ + RMB_CHECK_POINT_NULL (pStContext, "rmb_context_add_queue_pipe:pStContext"); + + int iRet = 0; + if (uiSize == 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_context_add_queue_pipe error!uiSize=%u", + uiSize); + rmb_errno = RMB_ERROR_SHM_PARA_ERROR; + return -1; + } + //init queue + StRmbQueue *pQue = (StRmbQueue *) calloc (1, sizeof (StRmbQueue)); + if (pQue == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_context_add_queue_pipe error!because calloc for queue failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + + iRet = rmb_queue_init (pQue, uiSize); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_context_add_queue_pipe error!because rmb_queue_init failed!"); + free (pQue); + rmb_errno = RMB_ERROR_INIT_MQ_FAIL; + return -3; + } + + StRmbPipe *pPipe = (StRmbPipe *) calloc (1, sizeof (StRmbPipe)); + if (pPipe == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_context_add_queue_pipe error!because calloc for pipe failed!"); + free (pQue); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -4; + } + + iRet = rmb_pipe_init (pPipe); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_context_add_queue_pipe error!becaulse rmb_pipe_init failed!"); + free (pPipe); + free (pQue); + rmb_errno = RMB_ERROR_INIT_FIFO_FAIL; + return -5; + } + + iRet = + rmb_wemq_notify_add (&pStContext->fifoMq, pQue, pPipe, iMsgType, func, + func_argv); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "context init error!because of rmb_notify_add failed!"); + free (pPipe); + free (pQue); + return -6; + } + + LOGRMB (RMB_LOG_INFO, "rmb_context_add_queue_pipe succ!"); + pRmbStConfig->iFlagForReq = (int) MSG_IPC_MQ; + return 0; +} + +//static int rmb_context_add_req_queue_pipe(StContext *pStContext, const unsigned int uiSize, rmb_callback_func func, void *func_msg, void* func_argv) +//{ +// return rmb_context_add_queue_pipe(pStContext, uiSize, wemq_req_mq_index, func, func_msg, func_argv); +//} +// +//static int rmb_context_add_rr_rsp_queue_pipe(StContext *pStContext, const unsigned int uiSize, rmb_callback_func func, void *func_msg, void* func_argv) +//{ +// return rmb_context_add_queue_pipe(pStContext, uiSize, wemq_rr_rsp_mq_index, func, func_msg, func_argv); +//} +// +//static int rmb_context_add_broadcast_queue_pipe(StContext *pStContext, const unsigned int uiSize, rmb_callback_func func, void *func_msg, void* func_argv) +//{ +// return rmb_context_add_queue_pipe(pStContext, uiSize, wemq_broadcast_mq_index, func, func_msg, func_argv); +//} +//////////////////////////////////////////////////////////////////////// + +int rmb_context_enqueue (StContext * pStContext, + const enum RmbMqIndex uiMsgType, const char *data, + unsigned int uiDataLen) +{ + pStContext->uiNowTime = time (NULL); + return rmb_notify_enqueue_by_type (&(pStContext->fifoMq), uiMsgType, + pStContext->uiNowTime, data, uiDataLen); +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_errno.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_errno.c new file mode 100644 index 0000000000..ffab955166 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_errno.c @@ -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. + +#include +#include +#include +#include +#include "rmb_errno.h" + +char *p_err_msg[RMB_MAX_ERR_NUMS] = { 0 }; + +struct rmb_err_msg rmb_err_msg_array[] = { + {RMB_ERROR_ARGV_NULL, "argv is null"}, + {RMB_ERROR_ARGV_LEN_ERROR, "argv len error"}, + {RMB_ERROR_MALLOC_FAIL, "malloc fail"}, + {RMB_ERROR_INIT_CONTEXT_FAIL, "init context fail"}, + {RMB_ERROR_MSG_MISSING_PART, "msg missing necessary part"}, + {RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG, + "rr interface can't send event msg"}, + {RMB_ERROR_EVENT_INTERFACE_CAN_NOT_SEND_RR_MSG, + "event msg can't send rr msg"}, + {RMB_ERROR_NOW_CAN_NOT_SEND_MSG, "now can't send msg"}, + {RMB_ERROR_QUEUE_FULL, "queue is full"}, + {RMB_ERROR_GSL_SERVICE_ID_NULL, "gsl service id null"}, + {RMB_ERROR_GSL_SERVICE_ID_ERROR, "gsl service id error"}, + {RMB_ERROR_GSL_SVR_ERROR, "gsl svr return error"}, + {RMB_ERROR_REQ_GSL_ERROR, "req gsl error"}, + {RMB_ERROR_MSG_UUID_FAIL, "msg generate uuid fail"}, + {RMB_ERROR_MSG_SET_SYSTEMHEADER_FAIL, "msg set systemheadfer fail"}, + {RMB_ERROR_SEND_GET_SESSION_FAIL, "send get session fail"}, + {RMB_ERROR_SEND_EVENT_MSG_FAIL, "send event msg fail"}, + {RMB_ERROR_SEND_RR_MSG_FAIL, "send rr msg fail"}, + {RMB_ERROR_SEND_RR_MSG_TIMEOUT, "send rr msg timeout"}, + {RMB_ERROR_REPLY_TO_NULL, "reply to is null"}, + {RMB_ERROR_REPLY_FAIL, "reply msg fail"}, + {RMB_ERROR_SESSION_CONNECT_FAIL, "session connect fail"}, + {RMB_ERROR_SESSION_RECONNECT_FAIL, "session reconnect fail"}, + {RMB_ERROR_SESSION_DESTORY_FAIL, "session destory fail"}, + {RMB_ERROR_SESSION_NUMS_LIMIT, "session nums limit"}, + {RMB_ERROR_LISTEN_QUEUE_NOT_EXIST, "listen queue not exist"}, + {RMB_ERROR_LISTEN_QUEUE_FAIL, "listen queue fail"}, + {RMB_ERROR_FLOW_DESTORY_FAIL, "flow destory fail"}, + {RMB_ERROR_LISTEN_TOPIC_FAIL, "listen topic fail"}, + {RMB_ERROR_INIT_MQ_FAIL, "init mq fail"}, + {RMB_ERROR_INIT_FIFO_FAIL, "init fifo fail"}, + {RMB_ERROR_INIT_UDP_FAIL, "init udp fail"}, + {RMB_ERROR_INIT_EPOLL_FAIL, "init epoll fail"}, + {RMB_ERROR_MQ_NUMS_LIMIT, "mq nums limit"}, + {RMB_ERROR_ENQUEUE_MQ_FAIL, "enqueue mq fail"}, + {RMB_ERROR_DEQUEUE_MQ_FAIL, "dequeue mq fail"}, + {RMB_ERROR_MSG_2_BUF_FAIL, "shift msg to buf fail"}, + {RMB_ERROR_BUF_2_MSG_FAIL, "shift buf to msg fail"}, + {RMB_ERROR_MSG_SET_CONTENT_TOO_LARGE, "msg set content too large"}, + {RMB_ERROR_MSG_SET_APPHEADER_TOO_LARGE, "msg set appheader too large"}, + {RMB_ERROR_MSG_TTL_0, "message ttl can't be 0"}, + {RMB_ERROR_RCV_MSG_GET_CONTENT_FAIL, "receive msg has no content"}, + {RMB_ERROR_RCV_MSG_GET_BINARY_FAIL, "receive msg has no binary"}, + {RMB_ERROR_RCV_MSG_CONTENT_TOO_LARGE, "receive msg content too large"}, + {RMB_ERROR_RCV_MSG_APPHEADER_TOO_LARGE, + "receive message appheader too large"}, + {RMB_ERROR_MANAGE_MSG_PKG_ERROR, "manage msg format error"}, + {RMB_ERROR_MANAGE_MSG_PKG_CHECK_FAIL, "manage msg check fail"}, + {RMB_ERROR_CONTEXT_CREATE_FAIL, "context create fail"}, + {RMB_ERROR_FIFO_PARA_ERROR, "fifo para error"}, + {RMB_ERROR_SHM_PARA_ERROR, "shm para error"}, + {RMB_ERROR_SEND_FIFO_NOTIFY_ERROR, "send notify fail"}, + {RMB_ERROR_FLOW_NUMS_LIMIT, "flow nums limit"}, + {RMB_ERROR_MSG_GET_SYSTEMHEADER_ERROR, "get system header error"}, + {RMB_ERROR_RMB_MSG_2_SOLACE_MSG_ERROR, "copy rmb msg 2 solace msg error"}, + {RMB_ERROR_SOLACE_MSG_2_RMB_MSG_ERROR, "copy solace msg 2 rmb msg error"}, + {RMB_ERROR_NO_AVAILABLE_SESSION, "no available session"}, + {RMB_ERROR_NO_BROADCAST_SESSION, "no broadcast session"}, + {RMB_ERROR_NO_AVAILABLE_CONTEXT, "no available context"}, + {RMB_ERROR_SET_FLOW_PROPETY, "set flow property fail"}, + {RMB_ERROR_ACK_MSG_FAIL, "ack msg fail"}, + {RMB_ERROR_LOGIC_NOTIFY_INIT, "notify for logic init error"}, + {RMB_ERROR_SESSION_ADD_FAIL, "session add fail"}, + {RMB_ERROR_WORKER_NUMS_LIMIT, "worker nums limit"}, + {RMB_ERROR_BUF_NOT_ENOUGH, "buf not enough"}, + {RMB_ERROR_STOP_FLOW_ERROR, "stop flow receive error"}, + {RMB_ERROR_DEQUEUE_MQ_EMPTY, "dequeue empty"}, + {RMB_ERROR_WORKER_WINDOW_FULL, "worker send window full"}, + {RMB_ERROR_WORKER_PUT_FIFO_ERROR, "worker put msg into fifo error"}, + {RMB_ERROR_START_CALL_FAIL, "send log for start call error"}, + {RMB_ERROR_END_CALL_FAIL, "send log for end call error"}, + {RMB_ERROR_ENTRY_FAIL, "send log for entry error"}, + {RMB_ERROR_EXIT_FAIL, "send log for exit error"}, + {RMB_ERROR_BASE_BEGIN, NULL} +}; + +static pthread_key_t rmb_user_key; +static pthread_once_t rmb_user_key_once = PTHREAD_ONCE_INIT; + +static void rmb_make_key () +{ + (void) pthread_key_create (&rmb_user_key, NULL); +} + +int *rmb_error () +{ + int *ptr; + + (void) pthread_once (&rmb_user_key_once, rmb_make_key); + if ((ptr = pthread_getspecific (rmb_user_key)) == NULL) + { + ptr = malloc (sizeof (int)); + memset (ptr, 0, sizeof (int)); + (void) pthread_setspecific (rmb_user_key, ptr); + } + return ptr; +} + +void init_error () +{ + int i = 0; + for (; rmb_err_msg_array[i].err_msg != NULL && i < RMB_MAX_ERR_NUMS; i++) + { + p_err_msg[rmb_err_msg_array[i].err_no - RMB_ERROR_BASE_BEGIN] = + rmb_err_msg_array[i].err_msg; + } + rmb_errno = 0; +} + +const char *get_rmb_last_error () +{ + if (rmb_errno == 0) + { + return "ok"; + } + if (rmb_errno <= RMB_ERROR_BASE_BEGIN + && rmb_errno >= RMB_ERROR_BASE_BEGIN + RMB_MAX_ERR_NUMS) + { + return "unknown errorno"; + } + return ((p_err_msg[rmb_errno - RMB_ERROR_BASE_BEGIN] == + NULL) ? "unknown errorno" : p_err_msg[rmb_errno - + RMB_ERROR_BASE_BEGIN]); +} + +void rmb_reset_error () +{ + rmb_errno = 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_http_client.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_http_client.c new file mode 100644 index 0000000000..acab4b0b4d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_http_client.c @@ -0,0 +1,211 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include "curl/curl.h" +#include "rmb_http_client.h" +#include "rmb_define.h" + +static pthread_mutex_t LIBCURL_LOCK = PTHREAD_MUTEX_INITIALIZER; +static int LIBCURL_INIT_FLAG = 0; + +static void atexit_callback (void) +{ + if (0 != LIBCURL_INIT_FLAG) + { +#ifdef RMB_HTTP_DEBUG + printf ("[Exit]curl_global_cleanup\n"); +#endif + curl_global_cleanup (); + LIBCURL_INIT_FLAG = 0; + } +} + +static void libcurl_init (void) +{ + pthread_mutex_lock (&LIBCURL_LOCK); + if (0 == LIBCURL_INIT_FLAG) + { +#ifdef RMB_HTTP_DEBUG + printf ("[INIT]curl_global_init\n"); +#endif + curl_global_init (CURL_GLOBAL_ALL); + atexit (atexit_callback); + LIBCURL_INIT_FLAG = 1; + } + pthread_mutex_unlock (&LIBCURL_LOCK); +} + +static int on_http_debug (CURL * handle, curl_infotype type, char *data, + size_t size, void *userptr) +{ + if (type == CURLINFO_TEXT) + { + //printf("[TEXT]%s\n", data); + } + else if (type == CURLINFO_HEADER_IN) + { + printf ("[HEADER_IN]%s\n", data); + } + else if (type == CURLINFO_HEADER_OUT) + { + printf ("[HEADER_OUT]%s\n", data); + } + else if (type == CURLINFO_DATA_IN) + { + printf ("[DATA_IN]%s\n", data); + } + else if (type == CURLINFO_DATA_OUT) + { + printf ("[DATA_OUT]%s\n", data); + } + return 0; +} + +static size_t on_http_body (char *ptr, size_t size, size_t nmemb, + void *userdata) +{ + size_t len = size * nmemb; + + if (ptr == NULL || userdata == NULL) + { + printf ("%s ptr is null\n", __func__); + return -1; + } + + struct rmb_http_buffer *buf = (struct rmb_http_buffer *) userdata; + + buf->data = + (char *) realloc (buf->data, sizeof (char) * (buf->len + len + 1)); + if (buf->data == NULL) + { + /* out of memory */ + printf ("not enough memory for realloc(buf->data)"); + return 0; + } + + memcpy (&(buf->data[buf->len]), ptr, len); + buf->len += len; + buf->data[buf->len] = '\0'; + + return len; +} + +int rmb_http_easy_get (const char *url, void *buffer, long timeout) +{ + CURLcode res; + CURL *curl = NULL; + struct curl_slist *headers = NULL; + + libcurl_init (); + curl = curl_easy_init (); + if (NULL == curl) + { + LOGRMB (RMB_LOG_ERROR, "curl_easy_init failed"); + return -1; + } + + struct rmb_http_buffer *response = (struct rmb_http_buffer *) buffer; + + headers = curl_slist_append (headers, "Connection: Keep-Alive"); + +#ifdef RMB_HTTP_DEBUG + curl_easy_setopt (curl, CURLOPT_VERBOSE, 1); + curl_easy_setopt (curl, CURLOPT_DEBUGFUNCTION, on_http_debug); +#endif + curl_easy_setopt (curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt (curl, CURLOPT_URL, url); + curl_easy_setopt (curl, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, on_http_body); + curl_easy_setopt (curl, CURLOPT_WRITEDATA, (void *) response); + curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT_MS, timeout); + curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, timeout); + res = curl_easy_perform (curl); + curl_easy_cleanup (curl); + curl_slist_free_all (headers); + + if (res == CURLE_COULDNT_CONNECT) + { + return 1; + } + + if (res != CURLE_OK) + { + LOGRMB (RMB_LOG_ERROR, "curl_easy_perform failed: %s\n", + curl_easy_strerror (res)); + return -2; + } + + return 0; +} + +/* +int rmb_http_easy_post(char* url, char* post_data, size_t len, void* buffer, size_t size, size_t* used, long timeout) +{ + CURLcode res; + CURL* curl = NULL; + struct curl_slist *headers = NULL; + struct http_buffer response; + + libcurl_init(); + curl = curl_easy_init(); + if (NULL == curl) + { + return -1; + } + + response.buf = (char*)buffer; + response.size = size; + response.len = 0; + headers = curl_slist_append(headers, "Connection: Keep-Alive"); + +#ifdef HTTP_DEBUG + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, on_http_debug); +#endif + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_URL, url); + + curl_easy_setopt(curl, CURLOPT_POST, 1); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)len); + + curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, on_http_body); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, timeout); + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, timeout); + res = curl_easy_perform(curl); + curl_easy_cleanup(curl); + + if (res == CURLE_COULDNT_CONNECT) { + return 1; + } + if (0 != res) { + return -1; + } + *used = response.len; + if (response.len >= response.size) { + return 2; + } + *(response.buf + response.len) = '\0'; + return 0; +} +*/ diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_log.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_log.c new file mode 100644 index 0000000000..2b04f39a32 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_log.c @@ -0,0 +1,1273 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "rmb_log.h" +#include +#include "string.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "rmb_define.h" +#include "string.h" +#include "rmb_access_config.h" +#include + +StRmbLog *pStRmbLog = NULL; + +struct tm currRmb; +struct tm lastRmb; +static char StatLogLevel[6][10] = + { "FATAL", "ERROR", "WARN ", "INFO", "DEBUG", "ALL" }; + +int GetRmbNowLongTime () +{ + struct timeval nowRmbTimeVal; + gettimeofday (&nowRmbTimeVal, NULL); + pRmbStConfig->ulNowTtime = + (unsigned long) nowRmbTimeVal.tv_sec * (unsigned long) 1000UL + + (unsigned long) nowRmbTimeVal.tv_usec / 1000UL; + return 0; +} + +char *RmbGetDateTimeStr (const time_t * mytime) +{ + static char s[50]; + currRmb = *localtime (mytime); + if (currRmb.tm_year > 50) + snprintf (s, sizeof (s), "%04d-%02d-%02d %02d:%02d:%02d", + currRmb.tm_year + 1900, currRmb.tm_mon + 1, currRmb.tm_mday, + currRmb.tm_hour, currRmb.tm_min, currRmb.tm_sec); + else + snprintf (s, sizeof (s), "%04d-%02d-%02d %02d:%02d:%02d", + currRmb.tm_year + 2000, currRmb.tm_mon + 1, currRmb.tm_mday, + currRmb.tm_hour, currRmb.tm_min, currRmb.tm_sec); + return s; +} + +char *RmbGetCurDateTimeStr () +{ + time_t mytime = time (NULL); + return RmbGetDateTimeStr (&mytime); +} + +char *RmbGetShortDateStr (const time_t * mytime) +{ + static char s[50]; + currRmb = *localtime (mytime); + if (currRmb.tm_year > 50) + snprintf (s, sizeof (s), "%04d%02d%02d", currRmb.tm_year + 1900, + currRmb.tm_mon + 1, currRmb.tm_mday); + else + snprintf (s, sizeof (s), "%04d%02d%02d", currRmb.tm_year + 2000, + currRmb.tm_mon + 1, currRmb.tm_mday); + + return s; +} + +char *RmbGetCurShortDateStr () +{ + time_t mytime = time (NULL); + return RmbGetShortDateStr (&mytime); +} + +int RmbIsOtherDay (time_t * newTime, time_t * oldTime) +{ + lastRmb = *localtime (oldTime); + currRmb = *localtime (newTime); + if (currRmb.tm_mday != lastRmb.tm_mday) + { + return 1; + } + return 0; +} + +int GetCurFileNum (FILE * fl) +{ + if (fl != NULL) + { + fscanf (fl, "%d %d %lu", &pStRmbLog->_curFileNo, &pStRmbLog->_curFileNums, + &pStRmbLog->_lastShiftTime); + } + return 0; +} + +int SetCurFileNum (FILE * fl) +{ + if (fl != NULL) + { + ftruncate (fileno (fl), 0); + rewind (fl); + fprintf (fl, "%d %d %lu", pStRmbLog->_curFileNo, pStRmbLog->_curFileNums, + pStRmbLog->_lastShiftTime); + } + return 0; +} + +int GetCurFileNumFromStatFile () +{ + FILE *fp = fopen (pStRmbLog->_logStatFileName, "r"); + if (fp == NULL) + { + return 0; + } + fscanf (fp, "%d %d %lu", &pStRmbLog->_curFileNo, &pStRmbLog->_curFileNums, + &pStRmbLog->_lastShiftTime); + fclose (fp); + return 0; +} + +int SetCurFileNumToStatFile () +{ + struct flock lock; + FILE *fp = fopen (pStRmbLog->_logStatFileName, "w"); + if (fp == NULL) + { + return 0; + } + int fd = fileno (fp); + lock.l_type = F_WRLCK; + lock.l_start = 0; + lock.l_whence = SEEK_SET; + lock.l_len = 0; + lock.l_pid = getpid (); + if (-1 != fcntl (fd, F_SETLKW, &lock)) + { +// printf("pid=%d set FileNo=%d.Num=%d", getpid(), pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + fprintf (fp, "%d %d", pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + fcntl (fd, F_SETLKW, &lock); + } + fclose (fp); + return 0; +} + +int ReloadCfg (int logLevel, int shiftType, const char *path, int maxFileSize, + int maxFileNum) +{ + int iRet = 0; + pStRmbLog->_para._logLevel = logLevel; + pStRmbLog->_para._shiftType = shiftType; + if (shiftType == 6) + { + pStRmbLog->_para._shiftType = (int) RMB_LOG_TYPE_CYCLE; + } + strncpy (pStRmbLog->_para._path, path, sizeof (pStRmbLog->_para._path) - 1); + snprintf (pStRmbLog->_logStatFileName, + sizeof (pStRmbLog->_logStatFileName) - 1, "%s.stat", path); + pStRmbLog->_para._maxFileSize = maxFileSize; + pStRmbLog->_para._maxFileNum = maxFileNum; + pStRmbLog->_lastShiftTime = time (NULL); + if (strlen (pStRmbLog->_para._path) == 0 + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_NORMAL) + { + pStRmbLog->_pLogFile = stdout; + pStRmbLog->_curFileNums = 1; + pStRmbLog->_para._shiftType = 0; + pStRmbLog->_lastShiftTime = 0; + return 0; + } + + if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_CYCLE) + { + iRet = GetCurStateFromRmbLogByCirCle (); + if (iRet != 0) + { + return -1; + } + } + else if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY_AND_CYCLE) + { + pStRmbLog->_para._shiftType = RMB_LOG_TYPE_DAILY; + iRet = GetCurStateFromRmbLogByDaily_V4 (); + if (iRet != 0) + { + return -1; + } + } + else + { + pStRmbLog->_para._shiftType = RMB_LOG_TYPE_CYCLE; + iRet = GetCurStateFromRmbLogByCirCle (); + if (iRet != 0) + { + return -1; + } + } + return 0; +} + +int InitRmbLogFile (int logLevel, int shiftType, const char *path, + int maxFileSize, int maxFileNum) +{ + int iRet = 0; + memset (&pRmbStConfig->gRmbLog, 0, sizeof (StRmbLog)); + pStRmbLog = &pRmbStConfig->gRmbLog; + pStRmbLog->_para._logLevel = logLevel; + + pStRmbLog->_para._shiftType = shiftType; + if (shiftType == 6) + { + pStRmbLog->_para._shiftType = (int) RMB_LOG_TYPE_CYCLE; + } + strncpy (pStRmbLog->_para._path, path, sizeof (pStRmbLog->_para._path) - 1); + snprintf (pStRmbLog->_logStatFileName, + sizeof (pStRmbLog->_logStatFileName) - 1, "%s.stat", path); + pStRmbLog->_para._maxFileSize = maxFileSize; + pStRmbLog->_para._maxFileNum = maxFileNum; + pStRmbLog->_lastShiftTime = time (NULL); + + //spin_lock_init(&logSpinLock); + pthread_mutex_init (&pStRmbLog->rmbLogMutex, NULL); + //printf("log init!!"); + //if len(path) = 0, use stdout + + if (strlen (pStRmbLog->_para._path) == 0 + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_NORMAL) + { + pStRmbLog->_pLogFile = stdout; + pStRmbLog->_curFileNums = 1; + pStRmbLog->_para._shiftType = 0; + pStRmbLog->_lastShiftTime = 0; + return 0; + } + + if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_CYCLE) + { + iRet = GetCurStateFromRmbLogByCirCle (); + if (iRet != 0) + { + return -1; + } + } + else if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY_AND_CYCLE) + { + pStRmbLog->_para._shiftType = RMB_LOG_TYPE_DAILY; + iRet = GetCurStateFromRmbLogByDaily_V4 (); + if (iRet != 0) + { + return -1; + } + } + else + { + pStRmbLog->_para._shiftType = RMB_LOG_TYPE_CYCLE; + iRet = GetCurStateFromRmbLogByCirCle (); + if (iRet != 0) + { + return -1; + } + } + return 0; +} + +int CloseRmbLog () +{ +// if(pStRmbLog->_pLogFile == NULL) +// { +// return 0; +// } +// fclose(pStRmbLog->_pLogFile); +// pStRmbLog->_pLogFile = NULL; +// return 0; + close (pStRmbLog->_fd); + pStRmbLog->_fd = -1; + return 0; +} + +int OpenRmbLog () +{ +// if (pStRmbLog->_pLogFile != NULL) +// { +// return 0; +// } +// printf("open file=%s", pStRmbLog->_logBaseFileName); +// if ((pStRmbLog->_pLogFile = fopen(pStRmbLog->_logBaseFileName, "a+")) == NULL) +// { +// pStRmbLog->_pLogFile = stdout; +// printf("openLog failed!fileName=%s, now select stdout!", pStRmbLog->_logBaseFileName); +// return -1; +// } +// printf("open file=%s succ", pStRmbLog->_logBaseFileName); + pStRmbLog->_fd = + open (pStRmbLog->_logBaseFileName, O_RDWR | O_CREAT | O_APPEND, 0666); + if (pStRmbLog->_fd == -1) + { + printf ("openLog failed!fileName=%s, now select stdout!", + pStRmbLog->_logBaseFileName); + pStRmbLog->_fd = 1; + return 0; + } + return 0; +} + +int OpenStateLog () +{ + pStRmbLog->_pStatFile = fopen (pStRmbLog->_logStatFileName, "a+"); + if (pStRmbLog->_pStatFile == NULL) + { + return 0; + } + return fileno (pStRmbLog->_pStatFile); +} + +int CloseStateLog () +{ + if (pStRmbLog->_pStatFile != NULL) + { + fclose (pStRmbLog->_pStatFile); + } + pStRmbLog->_pStatFile = NULL; + return 0; +} + +int FindNextDeleteLog (StDayInfo * dayInfo) +{ + //update next delete file name and time + int i = 0; + //找当天的 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + pStRmbLog->_toDeleteFileNo = + (pStRmbLog->_toDeleteFileNo + 1) % pStRmbLog->_para._maxFileNum; + if (pStRmbLog->_toDeleteFileNo == 0) + { + pStRmbLog->_toDeleteFileNo = 1; + } + + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s_%s.%d", + pStRmbLog->_para._path, + RmbGetShortDateStr ((time_t *) & pStRmbLog->_toDeleteTime), + pStRmbLog->_toDeleteFileNo); +// printf("check fileName=%s is exist or not!", pStRmbLog->_toDeleteFileName); + struct stat sb; + if (stat (pStRmbLog->_toDeleteFileName, &sb) != 0) + { +// printf("i=%u,logFile=%s not exist!", i, pStRmbLog->_toDeleteFileName); + break; + } +// printf("Next deleteNo=%u,deleteFileName=%s", pStRmbLog->_toDeleteFileNo, pStRmbLog->_toDeleteFileName); + return 0; + } + + int count = (time (NULL) - pStRmbLog->_toDeleteTime) / 60 * 60 * 24 + 1; + for (i = 1; i < count; i++) + { + pStRmbLog->_toDeleteTime = pStRmbLog->_toDeleteTime + 60 * 60 * 24; + GetDayInfo (dayInfo, &pStRmbLog->_toDeleteTime); + if (dayInfo->_curFileNum != 0) + { + pStRmbLog->_toDeleteFileNo = dayInfo->_deleteFileNo; + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s_%s.%d", + pStRmbLog->_para._path, + RmbGetShortDateStr ((time_t *) & pStRmbLog->_toDeleteTime), + pStRmbLog->_toDeleteFileNo); + break; + } + } + + return 0; +} + +int ShiftRmbLog (FILE * file) +{ + if (strlen (pStRmbLog->_para._path) == 0 + || pStRmbLog->_para._shiftType == RMB_LOG_TYPE_NORMAL) + { + return 0; + } + + if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_CYCLE) + { + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) < 0) + { + pStRmbLog->_curFileSize = 0; + } + else + { + pStRmbLog->_curFileSize = (int) pStRmbLog->gRmbSb.st_size; + } + + if (pStRmbLog->_curFileSize < pStRmbLog->_para._maxFileSize) + { + return 0; + } + + OpenRmbLog (); + //file lock + pStRmbLog->logFileLock.l_type = F_WRLCK; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_len = 0; + pStRmbLog->logFileLock.l_pid = getpid (); + if (-1 != fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock)) + { + int fd = OpenStateLog (); + pStRmbLog->logStateLock.l_type = F_WRLCK; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_len = 0; + pStRmbLog->logStateLock.l_pid = getpid (); + if (-1 != fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock)) + { + //GetCurFileNum(pStRmbLog->_pStatFile); + GetCurFileNum (pStRmbLog->_pStatFile); +// printf("pid=%d,getCurNo=%d,CurNums=%d", getpid(), pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + snprintf (pStRmbLog->_logFileName, + sizeof (pStRmbLog->_logFileName) - 1, "%s.%d", + pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) != -1 + && (int) pStRmbLog->gRmbSb.st_size >= + pStRmbLog->_para._maxFileSize) + { + pStRmbLog->_curFileNums += 1; + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + if (access (pStRmbLog->_logFileName, F_OK) == 0) + { +// printf("pid=%d remove file=%s,curNo=%d, curNum=%d", getpid(), pStRmbLog->_logFileName, pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + remove (pStRmbLog->_logFileName); + } + pStRmbLog->_curFileNums -= 1; + } + + if (access (pStRmbLog->_logBaseFileName, F_OK) == 0) + { +// printf("pid=%d rename %s-->%s, curNo=%d,curNum=%d", getpid(), pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName, pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + } + else + { +// printf("pid=%d baseFileName=%s not exist", getpid(), pStRmbLog->_logBaseFileName); + } + pStRmbLog->_curFileNo = + (pStRmbLog->_curFileNo + 1) % pStRmbLog->_para._maxFileNum; +// if (pStRmbLog->_curFileNo == 0) +// { +// pStRmbLog->_curFileNo = 1; +// } + SetCurFileNum (pStRmbLog->_pStatFile); + //snprintf(pStRmbLog->_logFileName, sizeof(pStRmbLog->_logFileName) - 1, "%s.%d", pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + } + +// printf("pid=%d setFileNum.curNo=%d curNum=%d", getpid(), pStRmbLog->_curFileNo, pStRmbLog->_curFileNums); + pStRmbLog->logStateLock.l_type = F_UNLCK; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_len = 0; + fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock); + } + CloseStateLog (); + +// printf("shift over!pid=%d, curNo=%d,curNum=%d, logFileName=%s", getpid(), pStRmbLog->_curFileNo, pStRmbLog->_curFileNums, pStRmbLog->_logFileName); + //strncpy(pStRmbLog->_toDeleteFileName, pStRmbLog->_logFileName, sizeof(pStRmbLog->_toDeleteFileName) - 1); + + pStRmbLog->logFileLock.l_type = F_UNLCK; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_len = 0; + fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock); + } + CloseRmbLog (); + return 0; + } + else if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY) + { + time_t curTime = time (NULL); + //日期变更发送滚动 + if (RmbIsOtherDay (&curTime, &pStRmbLog->_lastShiftTime)) + { + OpenRmbLog (); + //file lock + pStRmbLog->logFileLock.l_type = F_WRLCK; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_len = 0; + pStRmbLog->logFileLock.l_pid = getpid (); + if (-1 != fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock)) + { + int fd = OpenStateLog (); + pStRmbLog->logStateLock.l_type = F_WRLCK; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_len = 0; + pStRmbLog->logStateLock.l_pid = getpid (); + if (-1 != fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock)) + { + GetCurFileNum (pStRmbLog->_pStatFile); + snprintf (pStRmbLog->_logFileName, + sizeof (pStRmbLog->_logFileName) - 1, "%s.%d", + pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + + if (RmbIsOtherDay (&curTime, &pStRmbLog->_lastShiftTime)) + { + pStRmbLog->_curFileNums += 1; + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + if (access (pStRmbLog->_logFileName, F_OK) == 0) + { + remove (pStRmbLog->_logFileName); + } + pStRmbLog->_curFileNums -= 1; + } + if (access (pStRmbLog->_logBaseFileName, F_OK) == 0) + { + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + } + + snprintf (pStRmbLog->_logBaseFileName, + sizeof (pStRmbLog->_logBaseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&curTime)); + snprintf (pStRmbLog->_logFileName, + sizeof (pStRmbLog->_logFileName), "%s.0", + pStRmbLog->_logBaseFileName); + pStRmbLog->_curFileNo = 0; + pStRmbLog->_curFileNums = 0; + pStRmbLog->_lastShiftTime = curTime; + SetCurFileNum (pStRmbLog->_pStatFile); + } + else + { + snprintf (pStRmbLog->_logBaseFileName, + sizeof (pStRmbLog->_logBaseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&curTime)); + } + pStRmbLog->logStateLock.l_type = F_UNLCK; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_len = 0; + fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock); + } + CloseStateLog (); + + pStRmbLog->logFileLock.l_type = F_UNLCK; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_len = 0; + fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock); + } + CloseRmbLog (); + return 0; + } + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) < 0) + { + pStRmbLog->_curFileSize = 0; + } + else + { + pStRmbLog->_curFileSize = (int) pStRmbLog->gRmbSb.st_size; + } + + if (pStRmbLog->_curFileSize < pStRmbLog->_para._maxFileSize) + { + return 0; + } + + OpenRmbLog (); + //file lock + pStRmbLog->logFileLock.l_type = F_WRLCK; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_len = 0; + pStRmbLog->logFileLock.l_pid = getpid (); + if (-1 != fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock)) + { + int fd = OpenStateLog (); + pStRmbLog->logStateLock.l_type = F_WRLCK; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_len = 0; + pStRmbLog->logStateLock.l_pid = getpid (); + if (-1 != fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock)) + { + GetCurFileNum (pStRmbLog->_pStatFile); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName), + "%s.%d", pStRmbLog->_logBaseFileName, + pStRmbLog->_curFileNo); + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) != -1 + && (int) pStRmbLog->gRmbSb.st_size >= + pStRmbLog->_para._maxFileSize) + { + pStRmbLog->_curFileNums += 1; + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + if (access (pStRmbLog->_logFileName, F_OK) == 0) + { + remove (pStRmbLog->_logFileName); + } + pStRmbLog->_curFileNums -= 1; + } + //CloseZrdLog(); + if (access (pStRmbLog->_logBaseFileName, F_OK) == 0) + { + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + } + + pStRmbLog->_curFileNo = + (pStRmbLog->_curFileNo + 1) % pStRmbLog->_para._maxFileNum; +// if (pStRmbLog->_curFileNo == 0) +// { +// pStRmbLog->_curFileNo = 1; +// } + SetCurFileNum (pStRmbLog->_pStatFile); + + } + + pStRmbLog->logStateLock.l_type = F_UNLCK; + pStRmbLog->logStateLock.l_whence = SEEK_SET; + pStRmbLog->logStateLock.l_start = 0; + pStRmbLog->logStateLock.l_len = 0; + fcntl (fd, F_SETLKW, &pStRmbLog->logStateLock); + } + CloseStateLog (); + + pStRmbLog->logFileLock.l_type = F_UNLCK; + pStRmbLog->logFileLock.l_whence = SEEK_SET; + pStRmbLog->logFileLock.l_start = 0; + pStRmbLog->logFileLock.l_len = 0; + fcntl (pStRmbLog->_fd, F_SETLKW, &pStRmbLog->logFileLock); + } + CloseRmbLog (); + return 0; + } + else if (pStRmbLog->_para._shiftType == RMB_LOG_TYPE_DAILY_AND_CYCLE) + { + time_t curTime = time (NULL); + //日期变更发送滚动 + if (RmbIsOtherDay (&curTime, &pStRmbLog->_lastShiftTime)) + { + pStRmbLog->_curFileNums += 1; + //假如个数限制,则删除老的 + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + remove (pStRmbLog->_toDeleteFileName); + pStRmbLog->_curFileNums -= 1; + StDayInfo dayInfo; + FindNextDeleteLog (&dayInfo); + } + //GetCurStateFromRmbLogByDaily_V3(); //保证没有出错 + //rename + //CloseRmbLog(); + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + snprintf (pStRmbLog->_logBaseFileName, + sizeof (pStRmbLog->_logBaseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&curTime)); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName), + "%s_1.log", pStRmbLog->_logBaseFileName); + pStRmbLog->_curFileNo = 1; + //OpenRmbLog(); + return 0; + } + + if (stat (pStRmbLog->_logBaseFileName, &pStRmbLog->gRmbSb) < 0) + { + pStRmbLog->_curFileSize = 0; + } + else + { + pStRmbLog->_curFileSize = (int) pStRmbLog->gRmbSb.st_size; + } + + if (pStRmbLog->_curFileSize < pStRmbLog->_para._maxFileSize) + { + return 0; + } + //文件大小促发滚动 + pStRmbLog->_curFileNums += 1; + if (pStRmbLog->_curFileNums > pStRmbLog->_para._maxFileNum) + { + remove (pStRmbLog->_toDeleteFileName); + pStRmbLog->_curFileNums -= 1; + StDayInfo dayInfo; + FindNextDeleteLog (&dayInfo); + } + //rename + //CloseRmbLog(); + rename (pStRmbLog->_logBaseFileName, pStRmbLog->_logFileName); + pStRmbLog->_curFileNo += 1; + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName), + "%s_%d.log", pStRmbLog->_logBaseFileName, + pStRmbLog->_curFileNo); + //OpenRmbLog(); + return 0; + } + return 0; +} + +int LogRmb (int logLevel, const char *format, ...) +{ +// printf("logLevel=%u,sysLevel=%u,file=%p,baseFile=%s", +// logLevel, pStRmbLog->_para._logLevel, pStRmbLog->_pLogFile, pStRmbLog->_logBaseFileName); +// va_list ap1; +// va_start(ap1, format); +// printf(format, ap1); +// va_end(ap1); +// return 0; +// return ShiftRmbLog(pStRmbLog->_pLogFile); + + if (logLevel > pStRmbLog->_para._logLevel) + { + return 0; + } + + //pthread_spin_lock(&logSpinLock); + pthread_mutex_lock (&pStRmbLog->rmbLogMutex); + ShiftRmbLog (pStRmbLog->_pLogFile); + va_list ap; + if ((pStRmbLog->_pLogFile = + fopen (pStRmbLog->_logBaseFileName, "a+")) == NULL) + { + pStRmbLog->_pLogFile = stdout; + //printf("openLog failed!fileName=%s, now select stdout!", pStRmbLog->_logBaseFileName); + } + va_start (ap, format); + gettimeofday (&pStRmbLog->stLogTv, NULL); + fprintf (pStRmbLog->_pLogFile, "[%s][%s %03d][%d][%lu]", + StatLogLevel[logLevel], + RmbGetDateTimeStr ((const time_t *) &(pStRmbLog->stLogTv.tv_sec)), + (int) ((pStRmbLog->stLogTv.tv_usec) / 1000), pRmbStConfig->uiPid, + pthread_self ()); + vfprintf (pStRmbLog->_pLogFile, format, ap); + va_end (ap); + fprintf (pStRmbLog->_pLogFile, "\n"); + if (pStRmbLog->_pLogFile != stdout) + { + fclose (pStRmbLog->_pLogFile); + } + + //pthread_spin_unlock(&logSpinLock); + pthread_mutex_unlock (&pStRmbLog->rmbLogMutex); + return 0; +} + +//统计现在有几个日志,当前日志马上要被rename成什么,是不是需要促发删除 +int GetCurStateFromRmbLogByCirCle () +{ + pStRmbLog->_curFileNums = 1; + //unsigned int minModifyTime = 0; + //int i = 0; + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s.log", pStRmbLog->_para._path); + //strncpy(pStRmbLog->_logFileName, pStRmbLog->_logBaseFileName, sizeof(pStRmbLog->_logFileName) - 1); + pStRmbLog->_curFileNo = 0; + /* + for (i = 1; i < pStRmbLog->_para._maxFileNum ; i++) + { + snprintf(pStRmbLog->_logFileName, sizeof(pStRmbLog->_logFileName) - 1, "%s.%d", pStRmbLog->_logBaseFileName, i); + printf("log file:%s", pStRmbLog->_logFileName); + + struct stat sb; + if (stat (pStRmbLog->_logFileName, &sb) != 0) + { + //�ļ�������, ʹ�øñ�� + pStRmbLog->_curFileNo = i; + printf("logFile=%s not exist!", pStRmbLog->_logFileName); + break; + } + pStRmbLog->_curFileNums++; + + printf("fileName=%s,modifyTime=%lu", pStRmbLog->_logFileName, sb.st_mtime); + //ѭ����־, ��Ҫ������޸�ʱ��������� + if (minModifyTime == 0 || sb.st_mtime < minModifyTime) + { + pStRmbLog->_toDeleteFileNo = i; + minModifyTime = sb.st_mtime; + } + // if (sb.st_mtime > maxModifyTime) + // { + // pStRmbLog->_curFileNo = i; + // maxModifyTime = sb.st_mtime; + // } + } + */ + pStRmbLog->_curFileNums = 0; + GetCurFileNumFromStatFile (); +// if (pStRmbLog->_curFileNo == 0) +// { +// pStRmbLog->_curFileNo = pStRmbLog->_toDeleteFileNo; +// } + //SetCurFileNumToStatFile(); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.%d", + pStRmbLog->_logBaseFileName, pStRmbLog->_toDeleteFileNo); + //printf("Circle Log: curFileNo=%u", pStRmbLog->_curFileNo); + return 0; +} + +//统计现在有几个日志,当前日志马上要被rename成什么,是不是需要促发删除(按编号大小) +int GetCurStateFromRmbLogByDaily () +{ + pStRmbLog->_curFileNums = 1; + int i = 0; + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s_%s.log", pStRmbLog->_para._path, RmbGetCurShortDateStr ()); + //strncpy(pStRmbLog->_logFileName, pStRmbLog->_logBaseFileName, sizeof(pStRmbLog->_logFileName) - 1); + //int todayFileNo = 0; + unsigned int curTime = time (NULL); + //当天 + for (i = 1; i < pStRmbLog->_para._maxFileNum - 1; i++) + { + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, i); +// printf("GetCurStateFromRmbLogByDaily log file:%s", pStRmbLog->_logFileName); + + struct stat sb; + if (stat (pStRmbLog->_logFileName, &sb) != 0) + { + //file not exist, use it + pStRmbLog->_curFileNo = i; + //pStRmbLog->_curFileNums = i; +// printf("GetCurStateFromRmbLogByDaily logFile=%s not exist!", pStRmbLog->_logFileName); + break; + } + pStRmbLog->_toDeleteTime = curTime; + pStRmbLog->_curFileNums++; + } + + //unsigned int minModifyTime = 0; + char baseFileName[300] = { 0 }; + int j = 0; + int finishFlag = 0; + int deleteNo = 0; + //往前找 + for (i = 1; !finishFlag && i < pStRmbLog->_para._maxFileNum; i++) + { + pStRmbLog->_toDeleteFileNo = deleteNo; + pStRmbLog->_toDeleteTime = curTime - 60 * 60 * 24 * i; + snprintf (baseFileName, sizeof (baseFileName), "%s_%s.log", + pStRmbLog->_para._path, + RmbGetShortDateStr ((time_t *) & pStRmbLog->_toDeleteTime)); +// printf("%d_baseName=%s", i , baseFileName); + int iNotNullFlag = 0; + for (j = 1; j < pStRmbLog->_para._maxFileNum; j++) + { + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.%d", + baseFileName, i); +// printf("check fileName=%s is exist or not!", pStRmbLog->_toDeleteFileName); + struct stat sb; + if (stat (pStRmbLog->_toDeleteFileName, &sb) != 0) + { + if (iNotNullFlag == 1) + { +// printf("GetCurStateFromRmbLogByDaily logFile=%s not exist!", pStRmbLog->_toDeleteFileName); + break; + } + if (j == pStRmbLog->_para._maxFileNum - 1) + { + if (iNotNullFlag == 0) + { + finishFlag = 1; +// printf("GetCurStateFromRmbLogByDaily logFile=%s has't exist", pStRmbLog->_toDeleteFileName); + break; + } + } + + continue; + } + if (deleteNo == 0) + { + deleteNo = j; + } + iNotNullFlag = 1; + pStRmbLog->_curFileNums++; + } + } + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.1", baseFileName); +// printf("Status:curFileNums=%u,mayBeDeleteFileName=%s", pStRmbLog->_curFileNums, pStRmbLog->_toDeleteFileName); + return 0; +} + +int GetDayInfo (StDayInfo * dayInfo, time_t * curTime) +{ + int i = 0; + time_t minModifyTime = 0; + dayInfo->_deleteFileNo = 1; + dayInfo->_curFileNo = 0; + dayInfo->_curFileNum = 0; + + snprintf (dayInfo->_baseFileName, sizeof (dayInfo->_baseFileName), + "%s_%s.log", pStRmbLog->_para._path, + RmbGetShortDateStr (curTime)); + + //当天 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + snprintf (dayInfo->_logFileName, sizeof (dayInfo->_logFileName) - 1, + "%s.%d", dayInfo->_baseFileName, i); +// printf("GetDayInfo log file:%s", dayInfo->_logFileName); + + struct stat sb; + if (stat (dayInfo->_logFileName, &sb) != 0) + { + //file not exist, use it + if (dayInfo->_curFileNo == 0) + { + dayInfo->_curFileNo = i; + } +// printf("GetDayInfo logFile=%s not exist!", dayInfo->_logFileName); + continue; + //break; //之所以不用break, 因为存在消除该日期下其他日志的可能 + } + dayInfo->_curFileNum++; + //循环日志,需要按最后修改时间排序 + if (minModifyTime == 0 || sb.st_mtime < minModifyTime) + { + dayInfo->_deleteFileNo = i; + minModifyTime = sb.st_mtime; + } + } + return 0; +} + +int GetDayInfoWithBreak (StDayInfo * dayInfo, time_t * curTime) +{ + int i = 0; + time_t minModifyTime = 0; + dayInfo->_deleteFileNo = 1; + dayInfo->_curFileNo = 0; + dayInfo->_curFileNum = 0; + snprintf (dayInfo->_baseFileName, sizeof (dayInfo->_baseFileName), + "%s_%s.log", pStRmbLog->_para._path, + RmbGetShortDateStr (curTime)); + + //当天 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + snprintf (dayInfo->_logFileName, sizeof (dayInfo->_logFileName) - 1, + "%s.%d", dayInfo->_baseFileName, i); +// printf("GetDayInfoWithBreak log file:%s", dayInfo->_logFileName); + + struct stat sb; + if (stat (dayInfo->_logFileName, &sb) != 0) + { + //file not exist, use it + if (dayInfo->_curFileNo == 0) + { + dayInfo->_curFileNo = i; + } +// printf("GetDayInfoWithBreak logFile=%s not exist!", dayInfo->_logFileName); + break; + } + dayInfo->_curFileNum++; + //循环日志,需要按最后修改时间排序 + if (minModifyTime == 0 || sb.st_mtime < minModifyTime) + { + dayInfo->_deleteFileNo = i; + minModifyTime = sb.st_mtime; + } + } + return 0; +} + +//统计现在有几个日志,当前日志马上要被rename成什么,是不是需要促发删除(同一个日期,按修改日期滚动) +int GetCurStateFromRmbLogByDaily_V3 () +{ + pStRmbLog->_curFileNums = 1; + int i = 0; + //当前天 + time_t curTime = time (NULL); + StDayInfo dayInfo; + GetDayInfo (&dayInfo, &curTime); + if (dayInfo._curFileNo == 0) + { + pStRmbLog->_curFileNo = dayInfo._deleteFileNo; + } + else + { + pStRmbLog->_curFileNo = dayInfo._curFileNo; + } + pStRmbLog->_curFileNums += dayInfo._curFileNum; + pStRmbLog->_toDeleteFileNo = dayInfo._deleteFileNo; + pStRmbLog->_toDeleteTime = curTime; + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s_%s.log", pStRmbLog->_para._path, + RmbGetShortDateStr (&curTime)); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + + //往前数 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + curTime = curTime - 60 * 60 * 24; + GetDayInfo (&dayInfo, &curTime); + if (dayInfo._curFileNum != 0) + { + pStRmbLog->_curFileNums += dayInfo._curFileNum; + pStRmbLog->_toDeleteFileNo = dayInfo._deleteFileNo; + pStRmbLog->_toDeleteTime = curTime; + } + else + { + break; + } + + } + + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s_%s.%d", + pStRmbLog->_para._path, + RmbGetShortDateStr (&pStRmbLog->_toDeleteTime), + pStRmbLog->_toDeleteFileNo); +// printf("GetCurStateFromRmbLogByDaily_V3 Status:curFileNums=%u,mayBeDeleteFileName=%s", pStRmbLog->_curFileNums, pStRmbLog->_toDeleteFileName); + return 0; +} + +//统计现在有几个日志,当前日志马上要被rename成什么,是不是需要促发删除(同一个日期,按修改日期滚动) +int GetCurStateFromRmbLogByDaily_V2 () +{ + pStRmbLog->_curFileNums = 1; + int i = 0; + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s_%s.log", pStRmbLog->_para._path, RmbGetCurShortDateStr ()); + //strncpy(pStRmbLog->_logFileName, pStRmbLog->_logBaseFileName, sizeof(pStRmbLog->_logFileName) - 1); + //int todayFileNo = 0; + unsigned int curTime = time (NULL); + //unsigned int maxModifyTime = 0; + unsigned int minModifyTime = 0; + + pStRmbLog->_toDeleteFileNo = 1; + //当天 + for (i = 1; i < pStRmbLog->_para._maxFileNum; i++) + { + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, i); +// printf("GetCurStateFromRmbLogByDaily log file:%s", pStRmbLog->_logFileName); + + struct stat sb; + if (stat (pStRmbLog->_logFileName, &sb) != 0) + { + //file not exist, use it + pStRmbLog->_curFileNo = i; + +// printf("GetCurStateFromRmbLogByDaily logFile=%s not exist!", pStRmbLog->_logFileName); + break; + } + pStRmbLog->_toDeleteTime = curTime; + pStRmbLog->_curFileNums++; + + //循环日志,需要按最后修改时间排序 + if (minModifyTime == 0 || sb.st_mtime < minModifyTime) + { + pStRmbLog->_toDeleteFileNo = i; + minModifyTime = sb.st_mtime; + } + } + + char baseFileName[300] = { 0 }; + int j = 0; + int finishFlag = 0; + int deleteNo = 0; + //往前 + for (i = 1; !finishFlag && i < pStRmbLog->_para._maxFileNum; i++) + { + pStRmbLog->_toDeleteTime = curTime - 60 * 60 * 24 * i; + time_t uiDeleteTime = pStRmbLog->_toDeleteTime; + snprintf (baseFileName, sizeof (baseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&uiDeleteTime)); +// printf("%d_baseName=%s", i , baseFileName); + int iNotNullFlag = 0; + deleteNo = 0; + //针对每一天查找 + for (j = 1; j < pStRmbLog->_para._maxFileNum; j++) + { + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.%d", + baseFileName, j); +// printf("check fileName=%s is exist or not!", pStRmbLog->_toDeleteFileName); + struct stat sb; + if (stat (pStRmbLog->_toDeleteFileName, &sb) != 0) + { + if (iNotNullFlag == 1) + { +// printf("GetCurStateFromRmbLogByDaily logFile=%s not exist!", pStRmbLog->_toDeleteFileName); + break; + } + if (j == pStRmbLog->_para._maxFileNum - 1) + { + if (iNotNullFlag == 0) + { + finishFlag = 1; + pStRmbLog->_toDeleteTime = + pStRmbLog->_toDeleteTime + 60 * 60 * 24; +// printf("GetCurStateFromRmbLogByDaily logFile=%s has't exist", pStRmbLog->_toDeleteFileName); + break; + } + } + + continue; + } + if (deleteNo == 0) + { + deleteNo = j; + pStRmbLog->_toDeleteFileNo = deleteNo; //记录当前最应该删除的 + } + iNotNullFlag = 1; //表示前面不是空的,没有类似000111的情况 + pStRmbLog->_curFileNums++; + } + + } + time_t uiDeleteTime = pStRmbLog->_toDeleteTime; + snprintf (baseFileName, sizeof (baseFileName), "%s_%s.log", + pStRmbLog->_para._path, RmbGetShortDateStr (&uiDeleteTime)); + snprintf (pStRmbLog->_toDeleteFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1, "%s.%d", baseFileName, + pStRmbLog->_toDeleteFileNo); +// printf("Status:curFileNums=%u,mayBeDeleteFileName=%s", pStRmbLog->_curFileNums, pStRmbLog->_toDeleteFileName); + return 0; +} + +//只在当天滚 +int GetCurStateFromRmbLogByDaily_V4 () +{ + pStRmbLog->_curFileNums = 0; + //当前天 + /* + time_t curTime = time(NULL); + StDayInfo dayInfo; + GetDayInfoWithBreak(&dayInfo, &curTime); + if (dayInfo._curFileNo == 0) + { + pStRmbLog->_curFileNo = dayInfo._deleteFileNo; + } + else + { + pStRmbLog->_curFileNo = dayInfo._curFileNo; + } + pStRmbLog->_curFileNums = dayInfo._curFileNum; + pStRmbLog->_toDeleteFileNo = dayInfo._curFileNo; + pStRmbLog->_toDeleteTime = curTime; + */ + pStRmbLog->_curFileNo = 0; + time_t curTime = time (NULL); + pStRmbLog->_lastShiftTime = curTime; + GetCurFileNumFromStatFile (); + pStRmbLog->_toDeleteFileNo = pStRmbLog->_curFileNo; + + snprintf (pStRmbLog->_logBaseFileName, sizeof (pStRmbLog->_logBaseFileName), + "%s_%s.log", pStRmbLog->_para._path, + RmbGetShortDateStr (&curTime)); + snprintf (pStRmbLog->_logFileName, sizeof (pStRmbLog->_logFileName) - 1, + "%s.%d", pStRmbLog->_logBaseFileName, pStRmbLog->_curFileNo); + strncpy (pStRmbLog->_toDeleteFileName, pStRmbLog->_logFileName, + sizeof (pStRmbLog->_toDeleteFileName) - 1); + return 0; +} + +void _Log_Thread_func (void *args) +{ + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + unsigned long ulNowTime = + (unsigned long) nowTimeVal.tv_sec * (unsigned long) 1000UL + + (unsigned long) nowTimeVal.tv_usec / 1000UL; + unsigned long lastPrintTime = 0; + + struct timeval tv_now; + unsigned long ulLastGetConfigTime = 0; + unsigned long ulLastGetAccessTime = 0; + + // char url[512]; + // snprintf(url, sizeof(url), "http://%s:%d/%s/%s/%s/%s", pRmbStConfig->cConfigIp, pRmbStConfig->iConfigPort, RMB_REQ_SINGLE, RMB_WHITE_LIST_SND, pRmbStConfig->cConsumerSysId, pRmbStConfig->cRegion); + + while (1) + { + int i = 0; + if ((pRmbStConfig->iWemqUseHttpCfg == 1)) + { + gettimeofday (&tv_now, NULL); + if (tv_now.tv_sec > + (ulLastGetAccessTime + pRmbStConfig->getAccessIpPeriod)) + { + ulLastGetAccessTime = tv_now.tv_sec; + //int iRet = wemq_proxy_load_servers(cAccessIpUrl, pRmbStConfig->iConfigTimeout, pRmbStConfig->cWemqSavePath); + char cAccessIpUrl[512]; + char addrArr[15][50] = { 0 }; + int lenAddrs = 0; + char tmpAddrs[512] = { 0 }; + strcpy (tmpAddrs, pRmbStConfig->ConfigAddr); + LOGRMB (RMB_LOG_DEBUG, + "config center ip str is:%s,try get access ip from the %d config center in list,lists:", + tmpAddrs, pRmbStConfig->configIpPosInArr + 1); + split_str (tmpAddrs, addrArr, &lenAddrs); + int j = 0; + for (j = 0; j < lenAddrs; ++j) + { + LOGRMB (RMB_LOG_DEBUG, "%s", addrArr[j]); + } + if (lenAddrs == 0) + { + LOGRMB (RMB_LOG_ERROR, + "config center addr list len is 0,please check if configCenterAddrMulti is empty in conf file"); + return -1; + } + + int iRet = 0; + int i = 0; + for (i = 0; i < lenAddrs; ++i) + { + memset (&cAccessIpUrl, 0x00, sizeof (cAccessIpUrl)); + snprintf (cAccessIpUrl, sizeof (cAccessIpUrl), "%s/%s", + addrArr[(i + pRmbStConfig->configIpPosInArr) % lenAddrs], + WEMQ_ACCESS_SERVER); + LOGRMB (RMB_LOG_DEBUG, "try to get access addr from %s", + cAccessIpUrl); + iRet = + wemq_proxy_load_servers (cAccessIpUrl, + pRmbStConfig->iConfigTimeout); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_WARN, + "get access ip from %s failed,try next config center ip", + cAccessIpUrl); + continue; + } + else + { + LOGRMB (RMB_LOG_INFO, + "get all access ip list result=%d from url:%s", iRet, + cAccessIpUrl); + pRmbStConfig->configIpPosInArr = + pRmbStConfig->configIpPosInArr + i; + break; + } + } + + // free addrArr + } + } + + sleep (1); + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_mq.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_mq.c new file mode 100644 index 0000000000..c6e6dfd302 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_mq.c @@ -0,0 +1,1357 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "rmb_mq.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rmb_cfg.h" +#include "rmb_log.h" +#include "rmb_define.h" +#include +#include "rmb_pub.h" + +#define NO_CLEAR_FLAG 0 +#define CLEAR_FLAG 1 + +int rmb_notify_get_fator (const int iCount) +{ + if (iCount < 5000) + { + return iCount / 1000 + 1; + } + else if (iCount < 10000) + { + return 5; + } + else if (iCount < 20000) + { + return 8; + } + else if (iCount < 30000) + { + return 12; + } + else if (iCount < 50000) + { + return 20; + } + else if (iCount < 100000) + { + return 30; + } + return 40; +} + +//get shared mem +int rmb_mq_get_shm (StRmbMq * pMq, const unsigned int shmKey, + const unsigned int shmSize, const int flags, + const int bReadOnly) +{ + long lRet; + if ((pMq->ulShmId = shmget (shmKey, shmSize, flags)) == -1) + { + return -1; + } + if (1 == bReadOnly) + { + if ((lRet = (long) shmat (pMq->ulShmId, NULL, SHM_RDONLY)) == -1) + { + return -2; + } + } + else + { + if ((lRet = (long) shmat (pMq->ulShmId, NULL, 0)) == -1) + { + return -3; + } + } + pMq->pMqData = (char *) lRet; + return 0; +} + +//mq init +int rmb_mq_init (StRmbMq * pMq, const unsigned int shmKey, + const unsigned int shmSize, const int bCreate, + const int bReadOnly) +{ + if (shmSize <= C_RMB_MQ_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, "rmb_mq_init shmSize if too small=%d", + (int) shmSize); + return -1; + } + pMq->uiShmkey = shmKey; + pMq->uiShmSize = shmSize; + + int nFlag = 0666; + //pMq->mqStat.ulShmId = + int iRet = rmb_mq_get_shm (pMq, shmKey, shmSize, nFlag, bReadOnly); + if (iRet != 0) + { + if (bCreate) + { + nFlag = nFlag | IPC_CREAT; + iRet = rmb_mq_get_shm (pMq, shmKey, shmSize, nFlag, bReadOnly); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_mq_init get shm failed! has create,iRet=%d", iRet); + return -2; + } + if (!bReadOnly) + { + //memset(pMq->pMqData, 0, pMq->uiShmSize); + memset (pMq->pMqData, 0, C_RMB_MQ_HEAD_SIZE); // set head and tail + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "rmb_mq_init get shm failed! no create,iRet=%d", + iRet); + return -3; + } + } + + //init shm + pMq->pHead = (unsigned int *) pMq->pMqData; + pMq->pTail = (unsigned int *) (pMq->pMqData + sizeof (unsigned int)); + *(pMq->pHead) = 0; + *(pMq->pTail) = 0; + pMq->pBlock = (char *) (pMq->pTail + 1); + pMq->uiBlockSize = pMq->uiShmSize - C_RMB_MQ_HEAD_SIZE; + return 0; +} + +//mq_enqueue +//return -2: not enough space +int rmb_mq_enqueue (StRmbMq * pMq, const char *data, unsigned int uiDataLen, + unsigned int uiFLow) +{ + if (pMq == NULL || data == NULL) + { + LOGRMB (RMB_LOG_ERROR, "enqueue failed!pMq==NULL or data==NULL"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + + unsigned int uiHead = *pMq->pHead; + unsigned int uiTail = *pMq->pTail; + unsigned int uiFreeLen = + uiHead > uiTail ? uiHead - uiTail : uiHead + pMq->uiBlockSize - uiTail; + unsigned int uiTailLen = pMq->uiBlockSize - uiTail; + char *pBlock = pMq->pBlock; + + char sHead[C_RMB_MQ_PKG_HEAD_SIZE] = { 0 }; + unsigned int uiTotalLen = uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE; + + //1.if no enough space + if (uiFreeLen <= uiTotalLen) + { + return -2; + } + + memcpy (sHead, &uiTotalLen, sizeof (unsigned int)); + memcpy (sHead + sizeof (unsigned int), &uiFLow, sizeof (unsigned int)); + + //2.if tail space > 8+len + //copy 8 byte, copy data + if (uiTailLen >= uiTotalLen) + { + memcpy (pBlock + uiTail, sHead, C_RMB_MQ_PKG_HEAD_SIZE); + memcpy (pBlock + uiTail + C_RMB_MQ_PKG_HEAD_SIZE, data, uiDataLen); + //update tail + *pMq->pTail += (uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE); + + } + //3.if tail space > 8 && < 8+len + else if (uiTailLen >= C_RMB_MQ_PKG_HEAD_SIZE + && uiTailLen < C_RMB_MQ_PKG_HEAD_SIZE + uiDataLen) + { + // copy 8 byte + memcpy (pBlock + uiTail, sHead, C_RMB_MQ_PKG_HEAD_SIZE); + + // copy firstlen + unsigned int uiFirstLen = uiTailLen - C_RMB_MQ_PKG_HEAD_SIZE; + memcpy (pBlock + uiTail + C_RMB_MQ_PKG_HEAD_SIZE, data, uiFirstLen); + + // copy secondlen + unsigned int uiSecondLen = uiDataLen - uiFirstLen; + memcpy (pBlock, data + uiFirstLen, uiSecondLen); + + //update tail + unsigned int tail = + *pMq->pTail + uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE - pMq->uiBlockSize; + *pMq->pTail = tail; + } + //4.if tail space < 8 + else + { + //copy tail byte + memcpy (pBlock + uiTail, sHead, uiTailLen); + + //copy 8-tail byte + unsigned int uiSecondLen = C_RMB_MQ_PKG_HEAD_SIZE - uiTailLen; + memcpy (pBlock, sHead + uiTailLen, uiSecondLen); + + //copy data + memcpy (pBlock + uiSecondLen, data, uiDataLen); + + //update tail + *pMq->pTail = uiSecondLen + uiDataLen; + } + return 0; +} + +//mq_dequeue +int rmb_mq_dequeue (StRmbMq * pMq, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId) +{ + RMB_CHECK_POINT_NULL (pMq, "pMq"); + RMB_CHECK_POINT_NULL (pMq, "buf"); + RMB_CHECK_POINT_NULL (pMq, "pDataLen"); + + unsigned int uiHead = *pMq->pHead; + unsigned int uiTail = *pMq->pTail; + const char *pBlock = pMq->pBlock; + + if (uiHead == uiTail) + { + *pDataLen = 0; + return 0; + } + unsigned int uiUsedLen = + uiTail > uiHead ? uiTail - uiHead : uiTail + pMq->uiBlockSize - uiHead; + char sHead[C_RMB_MQ_PKG_HEAD_SIZE]; + + //1.get head + if (uiHead + C_RMB_MQ_PKG_HEAD_SIZE > pMq->uiBlockSize) + { + unsigned int uiFirstSize = pMq->uiBlockSize - uiHead; + unsigned int uiSecondSize = C_RMB_MQ_PKG_HEAD_SIZE - uiFirstSize; + memcpy (sHead, pBlock + uiHead, uiFirstSize); + memcpy (sHead + uiFirstSize, pBlock, uiSecondSize); + uiHead = uiSecondSize; + } + else + { + memcpy (sHead, pBlock + uiHead, C_RMB_MQ_PKG_HEAD_SIZE); + uiHead += C_RMB_MQ_PKG_HEAD_SIZE; + } + + //2.get meta data len + unsigned int uiTotalLen = *((unsigned int *) sHead); + if (pFlowId) + { + *pFlowId = *((unsigned *) (sHead + sizeof (unsigned int))); + } + + if (uiTotalLen > uiUsedLen) + { + LOGRMB (RMB_LOG_ERROR, "dequeue error!uiTotallen=%u > usedLen=%u", + uiTotalLen, uiUsedLen); + return -1; + } + + *pDataLen = uiTotalLen - C_RMB_MQ_PKG_HEAD_SIZE; + if (*pDataLen > uiBufSize) + { + LOGRMB (RMB_LOG_ERROR, + "dequeue error!buffer size=%u is not enough,at least=%u!", + uiBufSize, *pDataLen); + return -1; + } + + //3.memcpy the meata data + if (uiHead + *pDataLen > pMq->uiBlockSize) + { + unsigned int uiFirstSize = pMq->uiBlockSize - uiHead; + unsigned int uiSecondSize = *pDataLen - uiFirstSize; + memcpy (buf, pBlock + uiHead, uiFirstSize); + memcpy (buf + uiFirstSize, pBlock, uiSecondSize); + //update the head + *pMq->pHead = uiSecondSize; + } + else + { + memcpy (buf, pBlock + uiHead, *pDataLen); + //update the head + *pMq->pHead = uiHead + *pDataLen; + } + + return 0; +} + +//mq_try_deuque +int rmb_mq_try_dequeue (StRmbMq * pMq, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId) +{ + return rmb_mq_dequeue (pMq, buf, uiBufSize, pDataLen, pFlowId); +} + +//mq_get_stat +int rmb_mq_get_stat (StRmbMq * pMq) +{ + unsigned int uiHead = *pMq->pHead; + unsigned int uiTail = *pMq->pTail; + unsigned int uiFreeLen = + uiHead > uiTail ? uiHead - uiTail : uiHead + pMq->uiBlockSize - uiTail; + unsigned int uiUsedLen = + uiTail > uiHead ? uiTail - uiHead : uiTail + pMq->uiBlockSize - uiHead; + LOGRMB (RMB_LOG_ERROR, "Mq Stat:[head=%u,tail=%u,freeLen=%u,usedLen=%u]", + uiHead, uiTail, uiFreeLen, uiUsedLen); + return 0; +} + +//*****************************for rmb queue(private memory)************************************ +//queue init +int rmb_queue_init (StRmbQueue * pQue, const unsigned int size) +{ + if (size <= C_RMB_MQ_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, "rmb_queue_init size is too small=%u", size); + return -1; + } + + pQue->pData = (char *) malloc (sizeof (char) * size); + if (pQue->pData == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_queue_init malloc for pQue->pData failed"); + return -2; + } + + pQue->uiSize = size; + + pQue->pHead = (unsigned int *) pQue->pData; + pQue->pTail = (unsigned int *) (pQue->pData + sizeof (unsigned int)); + *(pQue->pHead) = 0; + *(pQue->pTail) = 0; + pQue->pBlock = (char *) (pQue->pTail + 1); + pQue->uiBlockSize = pQue->uiSize - C_RMB_MQ_HEAD_SIZE; + + return 0; +} + +int rmb_queue_enqueue (StRmbQueue * pQue, const char *data, + unsigned int uiDataLen, unsigned int uiFLow) +{ + RMB_CHECK_POINT_NULL (pQue, "StRmbQueue:pQue"); + RMB_CHECK_POINT_NULL (data, "StRmbQueue:data"); + + unsigned int uiHead = *pQue->pHead; + unsigned int uiTail = *pQue->pTail; + unsigned int uiFreeLen = + (uiHead > + uiTail) ? (uiHead - uiTail) : (uiHead + pQue->uiBlockSize - uiTail); + unsigned int uiTailLen = pQue->uiBlockSize - uiTail; + char *pBlock = pQue->pBlock; + + char sHead[C_RMB_MQ_PKG_HEAD_SIZE] = { 0 }; + unsigned int uiTotalLen = uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE; + + //1.if no enough space + if (uiFreeLen <= uiTotalLen) + { + return -2; + } + + memcpy (sHead, &uiTotalLen, sizeof (unsigned int)); + memcpy (sHead + sizeof (unsigned int), &uiFLow, sizeof (unsigned int)); + + //2.if tail space > 8+len + //copy 8 byte, copy data + if (uiTailLen >= uiTotalLen) + { + memcpy (pBlock + uiTail, sHead, C_RMB_MQ_PKG_HEAD_SIZE); + memcpy (pBlock + uiTail + C_RMB_MQ_PKG_HEAD_SIZE, data, uiDataLen); + //update tail + *pQue->pTail += (uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE); + } + //3.if tail space > 8 && < 8+len + else if (uiTailLen >= C_RMB_MQ_PKG_HEAD_SIZE + && uiTailLen < C_RMB_MQ_PKG_HEAD_SIZE + uiDataLen) + { + // copy 8 byte + memcpy (pBlock + uiTail, sHead, C_RMB_MQ_PKG_HEAD_SIZE); + + // copy firstlen + unsigned int uiFirstLen = uiTailLen - C_RMB_MQ_PKG_HEAD_SIZE; + memcpy (pBlock + uiTail + C_RMB_MQ_PKG_HEAD_SIZE, data, uiFirstLen); + + // copy secondlen + unsigned int uiSecondLen = uiDataLen - uiFirstLen; + memcpy (pBlock, data + uiFirstLen, uiSecondLen); + + //update tail + unsigned int tail = + *pQue->pTail + uiDataLen + C_RMB_MQ_PKG_HEAD_SIZE - pQue->uiBlockSize; + *pQue->pTail = tail; + } + //4.if tail space < 8 + else + { + //copy tail byte + memcpy (pBlock + uiTail, sHead, uiTailLen); + + //copy 8-tail byte + unsigned int uiSecondLen = C_RMB_MQ_PKG_HEAD_SIZE - uiTailLen; + memcpy (pBlock, sHead + uiTailLen, uiSecondLen); + + //copy data + memcpy (pBlock + uiSecondLen, data, uiDataLen); + + //update tail + *pQue->pTail = uiSecondLen + uiDataLen; + } + + return 0; +} + +int rmb_queue_dequeue (StRmbQueue * pQue, char *buf, unsigned int uiBufSize, + unsigned int *pDataLen, unsigned int *pFlowId) +{ + RMB_CHECK_POINT_NULL (pQue, "rmb_queue_dequeue:pQue"); + RMB_CHECK_POINT_NULL (buf, "rmb_queue_dequeue:buf"); + RMB_CHECK_POINT_NULL (pDataLen, "rmb_queue_dequeue:pDataLen"); + + unsigned int uiHead = *pQue->pHead; + unsigned int uiTail = *pQue->pTail; + const char *pBlock = pQue->pBlock; + + if (uiHead == uiTail) + { + *pDataLen = 0; + return 0; + } + unsigned int uiUsedLen = + uiTail > uiHead ? uiTail - uiHead : uiTail + pQue->uiBlockSize - uiHead; + char sHead[C_RMB_MQ_PKG_HEAD_SIZE]; + + //1.get head + if (uiHead + C_RMB_MQ_PKG_HEAD_SIZE > pQue->uiBlockSize) + { + unsigned int uiFirstSize = pQue->uiBlockSize - uiHead; + unsigned int uiSecondSize = C_RMB_MQ_PKG_HEAD_SIZE - uiFirstSize; + memcpy (sHead, pBlock + uiHead, uiFirstSize); + memcpy (sHead + uiFirstSize, pBlock, uiSecondSize); + uiHead = uiSecondSize; + } + else + { + memcpy (sHead, pBlock + uiHead, C_RMB_MQ_PKG_HEAD_SIZE); + uiHead += C_RMB_MQ_PKG_HEAD_SIZE; + } + + //2.get meta data len + unsigned int uiTotalLen = *((unsigned int *) sHead); + if (pFlowId) + { + *pFlowId = *((unsigned *) (sHead + sizeof (unsigned int))); + } + + if (uiTotalLen > uiUsedLen) + { + LOGRMB (RMB_LOG_ERROR, "dequeue error!uiTotallen=%u > usedLen=%u", + uiTotalLen, uiUsedLen); + return -1; + } + + *pDataLen = uiTotalLen - C_RMB_MQ_PKG_HEAD_SIZE; + if (*pDataLen > uiBufSize) + { + LOGRMB (RMB_LOG_ERROR, + "dequeue error!buffer size=%u is not enough,at least=%u!", + uiBufSize, *pDataLen); + return -1; + } + + //3.memcpy the meata data + if (uiHead + *pDataLen > pQue->uiBlockSize) + { + unsigned int uiFirstSize = pQue->uiBlockSize - uiHead; + unsigned int uiSecondSize = *pDataLen - uiFirstSize; + memcpy (buf, pBlock + uiHead, uiFirstSize); + memcpy (buf + uiFirstSize, pBlock, uiSecondSize); + //update the head + *pQue->pHead = uiSecondSize; + } + else + { + memcpy (buf, pBlock + uiHead, *pDataLen); + //update the head + *pQue->pHead = uiHead + *pDataLen; + } + + return 0; +} + +int rmb_queue_try_dequeue (StRmbQueue * pQue, char *buf, + unsigned int uiBufSize, unsigned int *pDataLen, + unsigned int *pFlowId) +{ + return rmb_queue_dequeue (pQue, buf, uiBufSize, pDataLen, pFlowId); +} + +int rmb_queue_get_stat (StRmbQueue * pQue) +{ + unsigned int uiHead = *pQue->pHead; + unsigned int uiTail = *pQue->pTail; + unsigned int uiFreeLen = + uiHead > uiTail ? uiHead - uiTail : uiHead + pQue->uiBlockSize - uiTail; + unsigned int uiUsedLen = + uiTail > uiHead ? uiTail - uiHead : uiTail + pQue->uiBlockSize - uiHead; + LOGRMB (RMB_LOG_ERROR, "queue Stat:[head=%u,tail=%u,freeLen=%u,usedLen=%u]", + uiHead, uiTail, uiFreeLen, uiUsedLen); + return 0; +} + +//*****************************for fifo**************************************** +//fifo init +//return -1 exist error +int rmb_fifo_init (StRmbFifo * pFifo, const char *strPath) +{ + errno = 0; + int mode = 0666 | O_NONBLOCK | O_NDELAY; + if ((mkfifo (strPath, mode)) < 0) + { + if (errno != EEXIST) + { + LOGRMB (RMB_LOG_ERROR, "fifo strPath=%s has exist", strPath); + return -1; + } + } + + if (pFifo->iFd != -1 && pFifo->iFd != 0) + { + close (pFifo->iFd); + pFifo->iFd = -1; + } + + if ((pFifo->iFd = open (strPath, O_RDWR)) < 0) + { + return -2; + } + if (pFifo->iFd > 1024) + { + close (pFifo->iFd); + return -3; + } + + int val = fcntl (pFifo->iFd, F_GETFL, 0); + + if (val == -1) + { + return -4; + } + + if (val & O_NONBLOCK) + { + return 0; + } + + int iRet = fcntl (pFifo->iFd, F_SETFL, val | O_NONBLOCK | O_NDELAY); + if (iRet < 0) + { + return -5; + } + return 0; +} + +//notify +int rmb_fifo_send (StRmbFifo * pFifo) +{ + int iRet = write (pFifo->iFd, "\0", 1); + //LOGRMB(RMB_LOG_DEBUG, "rmb_fifo_send succ!iRet=%d, fd=%d", iRet, pFifo->iFd); + if (iRet != 0) + { + //return -1; + } + return 0; +} + +//clear notify +int rmb_fifo_clear_flag (StRmbFifo * pFifo) +{ + static char buffer[1]; + read (pFifo->iFd, buffer, 1); + //LOGRMB(RMB_LOG_DEBUG, "rmb_fifo_clear_flag succ!fd=%d", pFifo->iFd); + return 0; +} + +//*****************************for pipe**************************************** +//pipe init +//return -1 exist error +int rmb_pipe_init (StRmbPipe * pPipe) +{ + RMB_CHECK_POINT_NULL (pPipe, "rmb_pipe_init:pPipe"); + + if (pipe (pPipe->fd) < 0) + { + LOGRMB (RMB_LOG_ERROR, "pipe failed\n"); + return -1; + } + + int val = fcntl (pPipe->fd[0], F_GETFL, 0); + if (val == -1) + { + LOGRMB (RMB_LOG_ERROR, "fcntl get fd[0] failed\n"); + return -2; + } + + int iRet = fcntl (pPipe->fd[0], F_SETFL, val | O_NONBLOCK | O_NDELAY); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "fcntl set fd[0] failed\n"); + return -3; + } + + val = fcntl (pPipe->fd[1], F_GETFL, 0); + if (val == -1) + { + LOGRMB (RMB_LOG_ERROR, "fcntl get fd[1] failed\n"); + return -2; + } + + iRet = fcntl (pPipe->fd[1], F_SETFL, val | O_NONBLOCK | O_NDELAY); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "fcntl set fd[1] failed\n"); + return -3; + } + + pPipe->r_fd = pPipe->fd[0]; + pPipe->w_fd = pPipe->fd[1]; + + return 0; +} + +//notify +int rmb_pipe_send (StRmbPipe * pPipe) +{ + RMB_CHECK_POINT_NULL (pPipe, "rmb_pipe_send:pPipe"); + + write (pPipe->w_fd, "\0", 1); + + return 0; +} + +//clear notify +int rmb_pipe_clear_flag (StRmbPipe * pPipe) +{ + RMB_CHECK_POINT_NULL (pPipe, "rmb_pipe_send:pPipe"); + + static char buffer[1]; + read (pPipe->r_fd, buffer, 1); + + return 0; +} + +//******************************for rmb mq notify******************************* +int rmb_notify_init (StRmbMqFifoNotify * pMqNotify) +{ + memset ((char *) pMqNotify, 0, sizeof (StRmbMqFifoNotify)); + if (pMqNotify->pBuf == NULL) + { + pMqNotify->pBuf = (char *) calloc (MAX_MQ_PKG_SIZE, sizeof (char)); + if (pMqNotify->pBuf == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_init error!calloc buf failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return rmb_errno; + } + } + + //epoll init + pMqNotify->iEpollFd = epoll_create (MAX_MQ_NUMS); + if (pMqNotify->iEpollFd < 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_init error!epoll_create failed!"); + rmb_errno = RMB_ERROR_INIT_EPOLL_FAIL; + return rmb_errno; + } + return 0; +} + +//notify add +int rmb_notify_add (StRmbMqFifoNotify * pMqNotify, StRmbMq * mq, + StRmbFifo * fifo, const enum RmbMqIndex iMsgType, + rmb_callback_func func, void *func_argv) +{ + if (pMqNotify->iMqNum >= MAX_MQ_NUMS) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_add error!mqCurNum=%d,maxNum=%d", + pMqNotify->iMqNum, MAX_MQ_NUMS); + rmb_errno = RMB_ERROR_MQ_NUMS_LIMIT; + return -1; + } + + if (pMqNotify->mqIndex[(int) iMsgType] != NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_add error!type:%d has add!!!", + (int) iMsgType); + return -1; + } + + pMqNotify->vecMqInfo[pMqNotify->iMqNum].mq = mq; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].fifo = fifo; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].que = NULL; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].pipe = NULL; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].func = func; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].args = func_argv; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMsgType = iMsgType; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iIndex = pMqNotify->iMqNum; + //add init mutex + pthread_mutex_init (&(pMqNotify->vecMqInfo[pMqNotify->iMqNum].queMutex), + NULL); + pMqNotify->mqIndex[(int) iMsgType] = + &(pMqNotify->vecMqInfo[pMqNotify->iMqNum]); + + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMergeNotifyFLag = 1; + if (func == NULL) + { + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMergeNotifyFLag = 0; + } + + //for select + FD_SET (fifo->iFd, &pMqNotify->readFd); + if (fifo->iFd >= pMqNotify->iMaxFd) + { + pMqNotify->iMaxFd = fifo->iFd + 1; + } + + //for epoll + struct epoll_event ev; + ev.events = EPOLLIN | EPOLLERR; + ev.data.fd = fifo->iFd; + ev.data.u32 = pMqNotify->iMqNum; + epoll_ctl (pMqNotify->iEpollFd, EPOLL_CTL_ADD, fifo->iFd, &ev); + pMqNotify->vecMqInfo[pMqNotify->iMqNum].active = 0; + + pMqNotify->iMqNum += 1; + return 0; +} + +int rmb_wemq_notify_add (StRmbMqFifoNotify * pMqNotify, StRmbQueue * que, + StRmbPipe * pipe, const enum RmbMqIndex iMsgType, + rmb_callback_func func, void *func_argv) +{ + if (pMqNotify->iMqNum >= MAX_MQ_NUMS) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_add error!mqCurNum=%d,maxNum=%d", + pMqNotify->iMqNum, MAX_MQ_NUMS); + rmb_errno = RMB_ERROR_MQ_NUMS_LIMIT; + return -1; + } + pMqNotify->vecMqInfo[pMqNotify->iMqNum].mq = NULL; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].fifo = NULL; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].que = que; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].pipe = pipe; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].func = func; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].args = func_argv; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMsgType = iMsgType; + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iIndex = pMqNotify->iMqNum; + pMqNotify->mqIndex[(int) iMsgType] = + &(pMqNotify->vecMqInfo[pMqNotify->iMqNum]); + + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMergeNotifyFLag = 1; + if (func == NULL) + { + pMqNotify->vecMqInfo[pMqNotify->iMqNum].iMergeNotifyFLag = 0; + } + + //for select + FD_SET (pipe->r_fd, &pMqNotify->readFd); + if (pipe->r_fd >= pMqNotify->iMaxFd) + { + pMqNotify->iMaxFd = pipe->r_fd + 1; + } + + //for epoll + struct epoll_event ev; + ev.events = EPOLLIN | EPOLLERR; + ev.data.fd = pipe->r_fd; + ev.data.u32 = pMqNotify->iMqNum; + epoll_ctl (pMqNotify->iEpollFd, EPOLL_CTL_ADD, pipe->r_fd, &ev); + pMqNotify->vecMqInfo[pMqNotify->iMqNum].active = 0; + + pMqNotify->iMqNum += 1; + return 0; +} + +int rmb_notify_enqueue_by_type_for_wemq (StRmbMqFifoNotify * pMqNotify, + const enum RmbMqIndex uiMsgType, + const unsigned int uiCurTime, + const char *data, + unsigned int uiDataLen) +{ + StMqInfo *pMqInfo = pMqNotify->mqIndex[(int) uiMsgType]; + if (pMqInfo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue_for_wemq error!pMqInfo is NULL"); + return -1; + } + + return rmb_notify_enqueue_for_wemq (uiCurTime, pMqInfo, data, uiDataLen); +} + +int rmb_notify_enqueue_for_wemq (const unsigned int uiCurTime, + StMqInfo * pMqInfo, const char *data, + unsigned int uiDataLen) +{ + if (pMqInfo == NULL || pMqInfo->que == NULL || pMqInfo->pipe == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue_for_wemq error!pMqInfo==NULL || pMqInfo->que==NULL || pMqInfo->pipe==NULL"); + return -1; + } + + int iRet = + rmb_queue_enqueue (pMqInfo->que, data, uiDataLen, pMqInfo->iMsgType); + if (iRet == -2) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue_for_wemq failed!queue full!"); + rmb_errno = RMB_ERROR_ENQUEUE_MQ_FAIL; + return -2; + } + else if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue_for_wemq failed!iRet=%d", + iRet); + return -3; + } + if (pMqInfo->iMergeNotifyFLag == 1) + { + if (uiCurTime >= + pMqInfo->uiLastCheckTime + pRmbStConfig->iNotifyCheckSpan) + { + pMqInfo->uiLastCheckTime = uiCurTime; + pMqInfo->iNotifyFactor = rmb_notify_get_fator (pMqInfo->iCount); + pMqInfo->iCount = 0; + } + else + { + pMqInfo->iCount++; + } + if (pMqInfo->iCount % pMqInfo->iNotifyFactor == 0) + { + iRet = rmb_pipe_send (pMqInfo->pipe); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue failed!rmb_pipe_send return iRet=%d", + iRet); + rmb_errno = RMB_ERROR_SEND_FIFO_NOTIFY_ERROR; + return -4; + } + } + } + else + { + iRet = rmb_pipe_send (pMqInfo->pipe); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue failed!rmb_pipe_send return iRet=%d", iRet); + rmb_errno = RMB_ERROR_SEND_FIFO_NOTIFY_ERROR; + return -5; + } + } + + return 0; +} + +//enqueue +int rmb_notify_enqueue_by_type (StRmbMqFifoNotify * pMqNotify, + const enum RmbMqIndex uiMsgType, + const unsigned int uiCurTime, + const char *data, unsigned int uiDataLen) +{ + StMqInfo *pMqInfo = pMqNotify->mqIndex[(int) uiMsgType]; + if (pMqInfo == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue error!pMqInfo == NULL"); + return -1; + } + return rmb_notify_enqueue (uiCurTime, pMqInfo, data, uiDataLen); +} + +//enqueue +//-1:error argv +//-2:not enough space +//-3:enquque error +//-4:notify send failed +int rmb_notify_enqueue (const unsigned int uiCurTime, StMqInfo * pMqInfo, + const char *data, unsigned int uiDataLen) +{ +// if (pMqInfo->iMsgType >= wemq_req_mq_index) { +// return rmb_notify_enqueue_for_wemq(uiCurTime, pMqInfo, data, uiDataLen); +// } + + pthread_mutex_lock (&pMqInfo->queMutex); + + //StMqInfo *pMqInfo = &(pMqNotify->vecMqInfo[(int)iOffset]); + if (pMqInfo->mq == NULL || pMqInfo->fifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue error!pMqInfo->mq == NULL || pMqInfo->fifo == NULL"); + rmb_errno = RMB_ERROR_ARGV_NULL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -1; + } + + int iRet = rmb_mq_enqueue (pMqInfo->mq, data, uiDataLen, pMqInfo->iMsgType); + if (iRet == -2) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue error!queue full!"); + rmb_errno = RMB_ERROR_ENQUEUE_MQ_FAIL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -2; + } + else if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue error!rmb_mq_enqueue iRet=%d", + iRet); + rmb_errno = RMB_ERROR_ENQUEUE_MQ_FAIL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -3; + } + if (pMqInfo->iMergeNotifyFLag == 1) + { + if (uiCurTime >= + pMqInfo->uiLastCheckTime + pRmbStConfig->iNotifyCheckSpan) + { + pMqInfo->uiLastCheckTime = uiCurTime; + pMqInfo->iNotifyFactor = rmb_notify_get_fator (pMqInfo->iCount); + pMqInfo->iCount = 0; + } + else + { + pMqInfo->iCount++; + } + if (pMqInfo->iCount % pMqInfo->iNotifyFactor == 0) + { + iRet = rmb_fifo_send (pMqInfo->fifo); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_enqueue error!rmb_fifo_send iRet=%d", iRet); + rmb_errno = RMB_ERROR_SEND_FIFO_NOTIFY_ERROR; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -4; + } + } + } + else + { + iRet = rmb_fifo_send (pMqInfo->fifo); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_enqueue error!rmb_fifo_send iRet=%d", + iRet); + rmb_errno = RMB_ERROR_SEND_FIFO_NOTIFY_ERROR; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -5; + } + } + pthread_mutex_unlock (&pMqInfo->queMutex); + return 0; +} + +int rmb_notify_dequeue_for_wemq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ + if (pMqInfo->que == NULL || pMqInfo->pipe == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_dequeue_for_wemq error!pMqInfo->que == NULL || pMqInfo->pipe == NULL"); + return -1; + } + + int iRet = rmb_queue_dequeue (pMqInfo->que, buf, uiBufSize, pDataLen, NULL); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_queue_dequeue error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + return -2; + } + + if (pMqInfo->iMergeNotifyFLag == 0) + { + iRet = rmb_pipe_clear_flag (pMqInfo->pipe); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue_for_wemq error!iRet=%d", + iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + return -2; + } + } + + return 0; +} + +//dequeue +int rmb_notify_dequeue (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, unsigned int *pDataLen) +{ +// if (pMqInfo->iMsgType >= wemq_req_mq_index) { +// return rmb_notify_dequeue_for_wemq(pMqInfo, buf, uiBufSize, pDataLen); +// } + + pthread_mutex_lock (&pMqInfo->queMutex); + //StMqInfo *pMqInfo = &(pMqNotify->vecMqInfo[(int)iOffset]); + if (pMqInfo->mq == NULL || pMqInfo->fifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_dequeue error!pMqInfo->mq == NULL || pMqInfo->fifo == NULL"); + rmb_errno = RMB_ERROR_ARGV_NULL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -1; + } + + int iRet = rmb_mq_dequeue (pMqInfo->mq, buf, uiBufSize, pDataLen, NULL); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!rmb_mq_dequeue iRet=%d", + iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + pthread_mutex_unlock (&pMqInfo->queMutex); + return -2; + } + if (pMqInfo->iMergeNotifyFLag == 0) + { + iRet = rmb_fifo_clear_flag (pMqInfo->fifo); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_dequeue error!rmb_fifo_clear_flag iRet=%d", iRet); + //return -3; + //return 0; + } + } + pthread_mutex_unlock (&pMqInfo->queMutex); + return 0; +} + +int rmb_notify_try_dequeue_for_wemq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ + if (pMqInfo == NULL || pMqInfo->que == NULL || pMqInfo->pipe == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_try_dequeue_for_wemq failed!pMqInfo==NULL or pMqInfo->que==NULL || pMqInfo->pipe==NULL"); + return -1; + } + + int iRet = + rmb_queue_try_dequeue (pMqInfo->que, buf, uiBufSize, pDataLen, NULL); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_queue_try_dequeue failed!iRet=%d", iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + return -2; + } + + if (*pDataLen == 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_try_dequeue_for_wemq failed!queue is empty"); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_EMPTY; + return -3; + } + + return 0; +} + +//try dequeue +int rmb_notify_try_dequeue (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ +// if (pMqInfo->iMsgType >= wemq_req_mq_index) { +// return rmb_notify_try_dequeue_for_wemq(pMqInfo, buf, uiBufSize, pDataLen); +// } + //StMqInfo *pMqInfo = &(pMqNotify->vecMqInfo[(int)iOffset]); + if (pMqInfo->mq == NULL || pMqInfo->fifo == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb_notify_dequeue error!pMqInfo->mq == NULL || pMqInfo->fifo == NULL"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + + pthread_mutex_lock (&pMqInfo->queMutex); + int iRet = rmb_mq_try_dequeue (pMqInfo->mq, buf, uiBufSize, pDataLen, NULL); + pthread_mutex_unlock (&pMqInfo->queMutex); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!rmb_mq_dequeue iRet=%d", + iRet); + rmb_errno = RMB_ERROR_DEQUEUE_MQ_FAIL; + return -2; + } + if (*pDataLen == 0) + { + rmb_errno = RMB_ERROR_DEQUEUE_MQ_EMPTY; + return -3; + } +// iRet = rmb_fifo_clear_flag(pMqInfo->fifo); +// if (iRet != 0) +// { +// printf("rmb_notify_dequeue error!rmb_fifo_clear_flag iRet=%d", iRet); +// return -3; +// } + return 0; +} + +//**************select or epoll************************* +//select fifo fd +//return >0 the mq index which has msg +// =0 all mq has no msg +// <0 all mq has no msg +static int rmb_notify_select (StRmbMqFifoNotify * pMqNotify, + unsigned int uiSec, unsigned int uiUsec) +{ + int i = 0; + int j = 0; + errno = 0; + StMqInfo *pMqInfo; + FD_ZERO (&(pMqNotify->tmpReadFd)); + pMqNotify->tmpReadFd = pMqNotify->readFd; + pMqNotify->tv.tv_sec = uiSec; + pMqNotify->tv.tv_usec = uiUsec; + int iRet = + select (pMqNotify->iMaxFd, &(pMqNotify->tmpReadFd), NULL, NULL, + &(pMqNotify->tv)); + if (iRet > 0) + { + for (i = 0; i < pMqNotify->iMqNum; i++) + { + if (FD_ISSET + (pMqNotify->vecMqInfo[i].fifo->iFd, &(pMqNotify->tmpReadFd))) + { + pMqInfo = &(pMqNotify->vecMqInfo[i]); + rmb_fifo_clear_flag (pMqInfo->fifo); + + for (j = 0; j < pRmbStConfig->iEveryTimeProcessNum; i++) + { + iRet = + rmb_notify_dequeue (&(pMqNotify->vecMqInfo[i]), pMqNotify->pBuf, + MAX_MQ_PKG_SIZE, &(pMqNotify->uiBufLen)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!iRet=%d", iRet); + break;; + } + if (pMqNotify->uiBufLen == 0) + { + break; + } + + pMqNotify->pBuf[pMqNotify->uiBufLen] = '\0'; + //shift_buf_2_msg((StRmbMsg *)pMqInfo->pReceiveMsg, pMqNotify->pBuf, pMqNotify->uiBufLen); + pMqInfo->func (pMqNotify->pBuf, pMqNotify->uiBufLen, pMqInfo->args); + } + } + } + } + else + { + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "select error!iRet=%d", iRet); + } + for (i = 0; i < pMqNotify->iMqNum; i++) + { + for (j = 0; j < pRmbStConfig->iEveryTimeProcessNum; i++) + { + iRet = + rmb_notify_dequeue (&(pMqNotify->vecMqInfo[i]), pMqNotify->pBuf, + MAX_MQ_PKG_SIZE, &(pMqNotify->uiBufLen)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!iRet=%d", iRet); + break;; + } + if (pMqNotify->uiBufLen == 0) + { + break; + } + + pMqNotify->pBuf[pMqNotify->uiBufLen] = '\0'; + //shift_buf_2_msg((StRmbMsg *)pMqInfo->pReceiveMsg, pMqNotify->pBuf, pMqNotify->uiBufLen); + pMqInfo = &pMqNotify->vecMqInfo[i]; + pMqInfo->func (pMqNotify->pBuf, pMqNotify->uiBufLen, pMqInfo->args); + + LOGRMB (RMB_LOG_ERROR, "try_dequee succ,j=%d!", j); + //rmb_mq_get_stat(pMqNotify->vecMqInfo[i].mq); + } + } + } + return 0; +} + +//***********************for epoll************************* +//epoll +int rmb_notify_epoll (StRmbSub * pStRmbSub, int iTimeout) +{ + StRmbMqFifoNotify *pMqNotify = &pStRmbSub->pStContext->fifoMq; + static struct epoll_event epv[MAX_MQ_NUMS]; + int iEventNum = + epoll_wait (pMqNotify->iEpollFd, epv, MAX_MQ_NUMS, iTimeout); + int iRet = 0; + StMqInfo *pMqInfo; + int i = 0; + int j = 0; + StRmbMsg *pReceiveMsg = rmb_msg_malloc (); + for (; i < iEventNum; ++i) + { + LOGRMB (RMB_LOG_DEBUG, "rmb_notify_epoll succ!num=%d,i=%d,eventNum=%d", + epv[i].data.u32, i, iEventNum); + pMqInfo = &(pMqNotify->vecMqInfo[epv[i].data.u32]); + + rmb_fifo_clear_flag (pMqInfo->fifo); + + for (j = 0; j < pRmbStConfig->iEveryTimeProcessNum; j++) + { + iRet = + rmb_notify_dequeue (pMqInfo, pMqNotify->pBuf, MAX_MQ_PKG_SIZE, + &(pMqNotify->uiBufLen)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!iRet=%d", iRet); + break; + } + if (pMqNotify->uiBufLen == 0) + { + break; + } + + pMqNotify->pBuf[pMqNotify->uiBufLen] = '\0'; + //rmb_send_log_for_func(pMqNotify->pBuf, pMqNotify->uiBufLen, RMB_CONTEXT_TYPE_SUB, pMqInfo->iMsgType); + shift_buf_2_msg (pReceiveMsg, pMqNotify->pBuf, pMqNotify->uiBufLen); + //do not filter + if (rmb_epoll_msg_filter (pStRmbSub, pReceiveMsg) == 0) + { + pRmbStConfig->mqIsEmpty = MQ_IS_NOT_EMPTY; + pMqInfo->func (pMqNotify->pBuf, pMqNotify->uiBufLen, pMqInfo->args); + wemq_sub_ack_msg (pStRmbSub, pReceiveMsg); + if (rmb_sub_check_mq_is_null (pStRmbSub) == 0) + { + pRmbStConfig->mqIsEmpty = MQ_IS_EMPTY; + } + pMqInfo->active = 1; + } + + } + } + + //for sure write fd is ok! + for (i = 0; i < pMqNotify->iMqNum; ++i) + { + pMqInfo = &pMqNotify->vecMqInfo[i]; + if (pMqInfo->active == 0) + { + for (j = 0; j < pRmbStConfig->iEveryTimeProcessNum; j++) + { + iRet = + rmb_notify_dequeue (pMqInfo, pMqNotify->pBuf, MAX_MQ_PKG_SIZE, + &(pMqNotify->uiBufLen)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_dequeue error!iRet=%d", iRet); + break; + } + if (pMqNotify->uiBufLen == 0) + { + break; + } + + pMqNotify->pBuf[pMqNotify->uiBufLen] = '\0'; + //rmb_send_log_for_func(pMqNotify->pBuf, pMqNotify->uiBufLen, RMB_CONTEXT_TYPE_SUB, pMqInfo->iMsgType); + shift_buf_2_msg (pReceiveMsg, pMqNotify->pBuf, pMqNotify->uiBufLen); + if (rmb_epoll_msg_filter (pStRmbSub, pReceiveMsg) == 0) + { + pRmbStConfig->mqIsEmpty = MQ_IS_NOT_EMPTY; + pMqInfo->func (pMqNotify->pBuf, pMqNotify->uiBufLen, pMqInfo->args); + wemq_sub_ack_msg (pStRmbSub, pReceiveMsg); + if (rmb_sub_check_mq_is_null (pStRmbSub) == 0) + { + pRmbStConfig->mqIsEmpty = MQ_IS_EMPTY; + } + } + } + } + else + { + pMqInfo->active = 0; + } + } + rmb_msg_free (pReceiveMsg); + + return 0; +} + +int rmb_epoll_msg_filter (StRmbSub * pStRmbSub, StRmbMsg * pReceiveMsg) +{ + RMB_CHECK_POINT_NULL (pStRmbSub, "pStRmbSub"); + RMB_CHECK_POINT_NULL (pReceiveMsg, "pReceiveMsg"); + //rr异步的包,直接返回 + if (pReceiveMsg->cPkgType == RR_TOPIC_PKG) + { + return 0; + } + + //监听模式下调用do_receive,过滤 + int iFlag = 1; + int i; + st_rmb_queue_info *p = pStRmbSub->pQueueInfo; + for (i = 0; i < pStRmbSub->iQueueNum; i++) + { + if (strcmp (pReceiveMsg->strServiceId, p->cServiceId) == 0) + { + iFlag = 0; + break; + } + p += 1; + } + + if (iFlag != 0) + { + LOGRMB (RMB_LOG_WARN, "pReceiveMsg bizseqno=%s not at listen topic!", + pReceiveMsg->sysHeader.cBizSeqNo); + return -2; + } + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_msg.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_msg.c new file mode 100644 index 0000000000..47c0c61c6f --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_msg.c @@ -0,0 +1,1686 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "uuid/uuid.h" +#include "common.h" +#include "rmb_msg.h" +#include "string.h" +#include "time.h" +#include "rmb_errno.h" + +static const int i1KB = 1 << 10; +static const int i2KB = 1 << 11; +static const int i4KB = 1 << 12; +static const int i8KB = 1 << 13; +static const int i16KB = 1 << 14; +static const int i32KB = 1 << 15; +static const int i64KB = 1 << 16; +static const int i128KB = 1 << 17; +static const int i256KB = 1 << 18; +static const int i512KB = 1 << 19; +static const int i1024KB = 1 << 20; +static const int i2048KB = 1 << 21; + +//private func +const static char *strLogicType[] = + { "null", "req_in", "rsp_in", "event_in", "req_out", "rsp_out", "event_out", +"null" }; + +int rmb_msg_clear (StRmbMsg * pStMsg) +{ + RMB_CHECK_POINT_NULL (pStMsg, "pStMsg"); + + //pStMsg->cPkgType = 0; + //pStMsg->cLogicType = 0; + memset (&(pStMsg->sysHeader), 0, sizeof (StSystemHeader)); + pStMsg->replyTo.cDestName[0] = '\0'; + pStMsg->dest.cDestName[0] = '\0'; + pStMsg->iCorrLen = 0; + pStMsg->iContentLen = 0; + pStMsg->iAppHeaderLen = 0; + pStMsg->ulMsgId = 0; + pStMsg->ulMsgLiveTime = 0; + //add in 2016-09-26 + pStMsg->flag = 0; + pStMsg->isDyedMsg[0] = "\0"; + return 0; +} + +int rmb_msg_init (StRmbMsg * pRmbMsg, StRmbConfig * pConfig, + enum RMB_API_YPE type) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + + pRmbMsg->replyTo.cDestName[0] = '\0'; + char cUniqueId[100] = { 0 }; + char cUniqueIdEx[50] = { 0 }; + rmb_msg_random_uuid (cUniqueIdEx, sizeof (cUniqueIdEx)); + snprintf (cUniqueId, sizeof (cUniqueId), "c/%s", cUniqueIdEx); +// pRmbMsg->cApiType = C_TYPE; + pRmbMsg->cApiType = type; + pRmbMsg->cLogicType = 0; + pRmbMsg->sysHeader.iReceiveMode = 1; + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSysId, pConfig->cConsumerSysId); + if (pRmbMsg->sysHeader.iSetSysVersionFlag != 1) + { //没有被用户设置过 + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSysVersion, + pConfig->cConsumerSysVersion); + } + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSvrId, pConfig->cHostIp); + RMB_MEMCPY (pRmbMsg->sysHeader.cOrgSvrId, pConfig->cHostIp); + RMB_MEMCPY (pRmbMsg->sysHeader.cUniqueId, cUniqueId); + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerDcn, pConfig->cConsumerDcn); + RMB_MEMCPY (pRmbMsg->sysHeader.cOrgId, pConfig->strOrgId); + RMB_MEMCPY (pRmbMsg->sysHeader.cRmbVersion, RMBVERSION); + + char cAppHeaderClassName[50] = "cn.webank.rmb.message.AppHeader"; + RMB_MEMCPY (pRmbMsg->sysHeader.cAppHeaderClass, cAppHeaderClassName); + + //RMB_MEMSET(pRmbMsg->strScenarioId); + //RMB_MEMSET(pRmbMsg->strServiceId); + //RMB_MEMSET(pRmbMsg->strTargetDcn); + //pRmbMsg->iEventOrService = 0; + + GetRmbNowLongTime (); + pRmbMsg->sysHeader.ulTranTimeStamp = pRmbStConfig->ulNowTtime; + pRmbMsg->sysHeader.ulMessageDate = pRmbStConfig->ulNowTtime; + + //for wemq + + return 0; +} + +//you must fill in under fields +int rmb_msg_set_bizSeqNo (StRmbMsg * pRmbMsg, const char *cBizSeqNo) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (cBizSeqNo, "cBizSeqNo"); + RMB_LEN_CHECK (cBizSeqNo, 32); + + RMB_MEMCPY (pRmbMsg->sysHeader.cBizSeqNo, cBizSeqNo); + return 0; +} + +int rmb_msg_set_consumerSysVersion (StRmbMsg * pRmbMsg, + const char *cConsumerSysVersion) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (cConsumerSysVersion, "cConsumerSysVersion"); + //RMB_LEN_CHECK(cBizSeqNo,32); + + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSysVersion, cConsumerSysVersion); + pRmbMsg->sysHeader.iSetSysVersionFlag = 1; + return 0; +} + +int rmb_msg_set_dyedMsg (StRmbMsg * pRmbMsg, const char *sign) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_MEMCPY (pRmbMsg->isDyedMsg, sign); + return 0; +} + +int rmb_msg_set_consumerSeqNo (StRmbMsg * pRmbMsg, const char *cConsumerSeqNo) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (cConsumerSeqNo, "cConsumerSeqNo"); + RMB_LEN_CHECK (cConsumerSeqNo, 32); + + RMB_MEMCPY (pRmbMsg->sysHeader.cConsumerSeqNo, cConsumerSeqNo); + return 0; +} + +int rmb_msg_set_orgSysId (StRmbMsg * pRmbMsg, const char *cOrgSysId) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (cOrgSysId, "cOrgSysId"); + RMB_LEN_CHECK (cOrgSysId, 4) + RMB_MEMCPY (pRmbMsg->sysHeader.cOrgSysId, cOrgSysId); + return 0; +} + +//*********************** + +int rmb_msg_set_dest (StRmbMsg * pRmbMsg, int desType, const char *cTargetDcn, + int iServiceOrEven, const char *cServiceId, + const char *cScenario) +{ + return rmb_msg_set_dest_v2 (pRmbMsg, cTargetDcn, cServiceId, cScenario); + +} + +int rmb_msg_set_dest_v2 (StRmbMsg * pRmbMsg, const char *cTargetDcn, + const char *cServiceId, const char *cScenario) +{ + return rmb_msg_set_dest_v2_1 (pRmbMsg, cTargetDcn, cServiceId, cScenario, + (char *) NULL); +} + +int rmb_msg_set_dest_v2_1 (StRmbMsg * pRmbMsg, const char *cTargetDcn, + const char *cServiceId, const char *cScenario, + const char *cTargetOrgId) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + //RMB_CHECK_POINT_NULL(cTargetDcn, "cTargetDcn"); + RMB_CHECK_POINT_NULL (cServiceId, "cServiceId"); + RMB_CHECK_POINT_NULL (cScenario, "cScenario"); + + if (cTargetDcn == NULL || strlen (cTargetDcn) == 0) + { + pRmbMsg->strTargetDcn[0] = 0; + } + else + { + if (strlen (cTargetDcn) != DEFAULT_DCN_LENGTH) + { + LOGRMB (RMB_LOG_ERROR, "destination dcn must be 3 length!input=%lu", + strlen (cTargetDcn)); + rmb_errno = RMB_ERROR_ARGV_LEN_ERROR; + return -2; + } + strncpy (pRmbMsg->strTargetDcn, cTargetDcn, + sizeof (pRmbMsg->strTargetDcn) - 1); + } + + if (strlen (cServiceId) != DEFAULT_SERVICE_ID_LENGTH) + { + LOGRMB (RMB_LOG_ERROR, + "destination service_id must be 8 length!input=%lu", + strlen (cServiceId)); + rmb_errno = RMB_ERROR_ARGV_LEN_ERROR; + return -2; + } + if (strlen (cScenario) != DEFAULT_SCENE_ID_LENGTH) + { + LOGRMB (RMB_LOG_ERROR, "destination scene_id must be 2 length!input=%lu", + strlen (cScenario)); + rmb_errno = RMB_ERROR_ARGV_LEN_ERROR; + return -2; + } + + pRmbMsg->iEventOrService = + (*(cServiceId + 3) == '0') ? RMB_SERVICE_CALL : RMB_EVENT_CALL; + + strncpy (pRmbMsg->strServiceId, cServiceId, + sizeof (pRmbMsg->strServiceId) - 1); + strncpy (pRmbMsg->strScenarioId, cScenario, + sizeof (pRmbMsg->strScenarioId) - 1); + if (cTargetOrgId == NULL) + { + pRmbMsg->iFLagForOrgId = RMB_COMMIT_BY_API; + } + else + { + pRmbMsg->iFLagForOrgId = RMB_COMMIT_BY_OWN; + strncpy (pRmbMsg->strTargetOrgId, cTargetOrgId, + sizeof (pRmbMsg->strTargetOrgId) - 1); + } + //modify 2016-09-26 + //pRmbMsg->flag = pRmbMsg->flag & (1 << RMBMSG_DEST_HAS_SET); + pRmbMsg->flag = pRmbMsg->flag | (1 << RMBMSG_DEST_HAS_SET); + + return 0; +} + +//////////////////1.7.3 add ////////////////////////////////////////////////////// + +//get dest +int rmb_msg_get_dest (StRmbMsg * pRmbMsg, char *dest, unsigned int *uiLen) +{ + if (pRmbMsg == NULL || dest == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or dest is null"); + return -1; + } + + if (*uiLen < strlen (pRmbMsg->dest.cDestName)) + { + LOGRMB (RMB_LOG_ERROR, "dest is too small, len=%u, but msg_dest_len=%u\n", + *uiLen, strlen (pRmbMsg->dest.cDestName)); + return -2; + } + + memcpy (dest, pRmbMsg->dest.cDestName, strlen (pRmbMsg->dest.cDestName)); + *uiLen = strlen (pRmbMsg->dest.cDestName); + + return 0; +} + +const char *rmb_msg_get_dest_ptr (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg is null"); + return NULL; + } + + return pRmbMsg->dest.cDestName; +} + +//get cConsumerSysId +int rmb_msg_get_consumerSysId (StRmbMsg * pRmbMsg, char *cConsumerSysId, + unsigned int *uiLen) +{ + if (pRmbMsg == NULL || cConsumerSysId == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or cConsumerSysId is null"); + return -1; + } + + unsigned int uiConsumerLen = + (unsigned int) strlen (pRmbMsg->sysHeader.cConsumerSysId); + + if (*uiLen < uiConsumerLen) + { + LOGRMB (RMB_LOG_ERROR, + "rmb msg consumerSysId len=%u, but arg len=%u(too small)", + uiConsumerLen, *uiLen); + return -2; + } + + memcpy (cConsumerSysId, pRmbMsg->sysHeader.cConsumerSysId, uiConsumerLen); + *uiLen = uiConsumerLen; + + return 0; +} + +const char *rmb_msg_get_consumerSysId_ptr (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg is null"); + return NULL; + } + + return pRmbMsg->sysHeader.cConsumerSysId; +} + +//get cConsumerSvrId +int rmb_msg_get_consumerSvrId (StRmbMsg * pRmbMsg, char *cConsumerSvrId, + unsigned int *uiLen) +{ + if (pRmbMsg == NULL || cConsumerSvrId == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or cConsumerSvrId is null"); + return -1; + } + + unsigned int uiConsumerLen = + (unsigned int) strlen (pRmbMsg->sysHeader.cConsumerSvrId); + + if (*uiLen < uiConsumerLen) + { + LOGRMB (RMB_LOG_ERROR, + "rmb msg consumerSvrId len=%u, but arg len=%u(too small)", + uiConsumerLen, *uiLen); + return -2; + } + + memcpy (cConsumerSvrId, pRmbMsg->sysHeader.cConsumerSvrId, uiConsumerLen); + *uiLen = uiConsumerLen; + + return 0; +} + +const char *rmb_msg_get_consumerSvrId_ptr (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg is null"); + return NULL; + } + + return pRmbMsg->sysHeader.cConsumerSvrId; +} + +////////////////////////////////////////////////////////////////////////////// + +int rmb_check_msg_valid (StRmbMsg * pStMsg) +{ + //modify in 2016-09-26 + //if (pStMsg->flag | (1 << RMBMSG_DEST_HAS_SET == 0)) + if ((pStMsg->flag & (1 << RMBMSG_DEST_HAS_SET)) == 0) + { + LOGRMB (RMB_LOG_ERROR, "pStMsg=%s must be init first!", + rmb_msg_print (pStMsg)); + rmb_errno = RMB_ERROR_MSG_MISSING_PART; + return -1; + } + return 0; +} + +int rmb_msg_set_live_time (StRmbMsg * pRmbMsg, unsigned long ulLiveTime) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + if (ulLiveTime == 0) + { + LOGRMB (RMB_LOG_ERROR, "ttl time must gt 0"); + rmb_errno = RMB_ERROR_MSG_TTL_0; + return -2; + } + + pRmbMsg->ulMsgLiveTime = ulLiveTime; + return 0; +} + +int rmb_get_fit_size (const unsigned int uiLen, const unsigned int uiMaxLen) +{ +// if (uiLen >= uiMaxLen) + if (uiLen > uiMaxLen) + { + return -1; + } + unsigned int uiCount = 0; + unsigned int uiTmpLen = uiLen; + while ((uiTmpLen = uiTmpLen >> 1) != 0) + { + uiCount++; + } + uiCount++; + uiCount = (uiCount >= 10) ? uiCount : 10; + return (1 << uiCount) + 1; +} + +int rmb_msg_set_app_header (StRmbMsg * pRmbMsg, const char *appHeader, + unsigned int uiLen) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (appHeader, "appHeader"); + +// if (uiLen >= MAX_APPHEADER_LENGTH) +// { +// LOGRMB(RMB_LOG_ERROR, "uiLen=%u too large!max_limit=%u", uiLen, MAX_APPHEADER_LENGTH); +// rmb_errno = RMB_ERROR_MSG_SET_APPHEADER_TOO_LARGE; +// return -2; +// } + if (pRmbMsg->cAppHeader == NULL || pRmbMsg->iMallocAppHeaderLength == 0) + { + pRmbMsg->cAppHeader = (char *) malloc (i1KB); + pRmbMsg->iMallocAppHeaderLength = i1KB; + } + if (uiLen >= pRmbMsg->iMallocAppHeaderLength) + { + int iFitSize = rmb_get_fit_size (uiLen, MAX_APPHEADER_LENGTH); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "uiLen=%u too large!max_limit=%u\n", uiLen, + MAX_APPHEADER_LENGTH); + rmb_errno = RMB_ERROR_BUF_NOT_ENOUGH; + return -2; + } + free (pRmbMsg->cAppHeader); + pRmbMsg->cAppHeader = NULL; + pRmbMsg->cAppHeader = (char *) malloc (iFitSize); + pRmbMsg->iMallocAppHeaderLength = iFitSize; + } + + memcpy (pRmbMsg->cAppHeader, appHeader, uiLen); + pRmbMsg->cAppHeader[uiLen] = '\0'; + pRmbMsg->iAppHeaderLen = (int) uiLen; + return 0; +} + +int rmb_msg_set_content (StRmbMsg * pRmbMsg, const char *content, + unsigned int uiLen) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (content, "content"); + +// if (uiLen >= sizeof(pRmbMsg->cContent)) +// { +// LOGRMB(RMB_LOG_ERROR, "uiLen=%u too large!max_limit=%lu",uiLen, sizeof(pRmbMsg->cContent)); +// rmb_errno = RMB_ERROR_MSG_SET_CONTENT_TOO_LARGE; +// return -2; +// } + + if (pRmbMsg->cContent == NULL || pRmbMsg->iMallocContentLength == 0) + { + pRmbMsg->cContent = (char *) malloc (i1KB); + pRmbMsg->iMallocContentLength = i1KB; + } + if (uiLen >= pRmbMsg->iMallocContentLength) + { + int iFitSize = rmb_get_fit_size (uiLen, MAX_MSG_CONTENT_SIZE); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "uiLen=%u too large!max_limit=%u\n", uiLen, + MAX_MSG_CONTENT_SIZE); + rmb_errno = RMB_ERROR_BUF_NOT_ENOUGH; + return rmb_errno; + } + free (pRmbMsg->cContent); + pRmbMsg->cContent = NULL; + pRmbMsg->cContent = (char *) malloc (iFitSize); + pRmbMsg->iMallocContentLength = iFitSize; + } + + memcpy (pRmbMsg->cContent, content, uiLen); + pRmbMsg->cContent[uiLen] = '\0'; + pRmbMsg->iContentLen = (int) uiLen; + pRmbMsg->sysHeader.iContentLength = pRmbMsg->iContentLen; + return 0; +} + +/** + * get msg type + * 0: undefined type + * 1: request in queue + * 2: reply package in RR + * 3: broadcast + * see: C_RMB_PKG_TYPE + */ +int rmb_msg_get_msg_type (StRmbMsg * pRmbMsg) +{ + return (int) pRmbMsg->cPkgType; +} + +const char *rmb_msg_get_uniqueId_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cUniqueId; +} + +const char *rmb_msg_get_biz_seq_no_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cBizSeqNo; +} + +const char *rmb_msg_get_consumer_seq_no_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cConsumerSeqNo; +} + +const char *rmb_msg_get_consumer_dcn_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cConsumerDcn; +} + +const char *rmb_msg_get_org_sys_id_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cOrgSysId; +} + +const char *rmb_msg_get_org_id_ptr (StRmbMsg * pRmbMsg) +{ + return pRmbMsg->sysHeader.cOrgId; +} + +const char *rmb_msg_get_app_header_ptr (StRmbMsg * pRmbMsg, + unsigned int *pLen) +{ + if (pRmbMsg == NULL || pLen == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or pLen == NULL"); + } + + *pLen = pRmbMsg->iAppHeaderLen; + return pRmbMsg->cAppHeader; +} + +int rmb_msg_get_app_header (StRmbMsg * pRmbMsg, char *userHeader, + unsigned int *pLen) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (userHeader, "userHeader"); + + if (pRmbMsg->iAppHeaderLen > *pLen) + { + LOGRMB (RMB_LOG_ERROR, " buffer len too small.uiLen=%u,buffSize=%u", + *pLen, pRmbMsg->iAppHeaderLen); + rmb_errno = RMB_ERROR_BUF_NOT_ENOUGH; + return rmb_errno; + } + memcpy (userHeader, pRmbMsg->cAppHeader, pRmbMsg->iAppHeaderLen); + *pLen = pRmbMsg->iAppHeaderLen; + return 0; +} + +const char *rmb_msg_get_content_ptr (StRmbMsg * pRmbMsg, unsigned int *pLen) +{ + if (pRmbMsg == NULL || pLen == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbMsg or pLen == NULL"); + } + + *pLen = pRmbMsg->iContentLen; + return pRmbMsg->cContent; +} + +int rmb_msg_get_content (StRmbMsg * pRmbMsg, char *content, + unsigned int *pLen) +{ + RMB_CHECK_POINT_NULL (pRmbMsg, "pRmbMsg"); + RMB_CHECK_POINT_NULL (content, "content"); + + if (pRmbMsg->iContentLen > *pLen) + { + LOGRMB (RMB_LOG_ERROR, + " content buffer len too small.uiLen=%u,buffSize=%u", *pLen, + pRmbMsg->iContentLen); + rmb_errno = RMB_ERROR_BUF_NOT_ENOUGH; + return rmb_errno; + } + memcpy (content, pRmbMsg->cContent, pRmbMsg->iContentLen); + *pLen = pRmbMsg->iContentLen; + return 0; +} + +int shift_buf_2_msg (StRmbMsg * pStMsg, const char *cBuf, unsigned int uiLen) +{ + //StRmbMsg msg; + const char *p = cBuf; + + unsigned int uiBufLen = + 3 * sizeof (char) + sizeof (pStMsg->sysHeader) + + 2 * sizeof (pStMsg->dest) + 2 * sizeof (unsigned long) + + 3 * sizeof (int) + sizeof (StFlow *) + sizeof (pStMsg->strTargetDcn) + + sizeof (pStMsg->strServiceId) + sizeof (pStMsg->strScenarioId) + + sizeof (int) + sizeof (int); + if (uiBufLen > uiLen) + { + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -1; + } + + //copy msg src + memcpy (&pStMsg->iMsgMode, p, sizeof (int)); + p += sizeof (int); + + //copy cPkgType + pStMsg->cPkgType = *p; + p += sizeof (char); + + //copy cLogicType + pStMsg->cLogicType = *p; + p += sizeof (char); + + //copy cApiType + pStMsg->cApiType = *p; + p += sizeof (char); + + //copy sysHeader + memcpy (&pStMsg->sysHeader, p, sizeof (pStMsg->sysHeader)); + p += sizeof (pStMsg->sysHeader); + + //copy dest + memcpy (&pStMsg->dest, p, sizeof (pStMsg->dest)); + p += sizeof (pStMsg->dest); + + //copy replyTo + memcpy (&pStMsg->replyTo, p, sizeof (pStMsg->replyTo)); + p += sizeof (pStMsg->replyTo); + + //copy msgid + memcpy (&pStMsg->ulMsgId, p, sizeof (unsigned long)); + p += sizeof (unsigned long); + + //copy msgLiveTime + memcpy (&pStMsg->ulMsgLiveTime, p, sizeof (unsigned long)); + p += sizeof (unsigned long); + + //copy AppHeader -- len + memcpy (&pStMsg->iAppHeaderLen, p, sizeof (int)); + p += sizeof (int); + + uiBufLen += pStMsg->iAppHeaderLen; + if (pStMsg->iAppHeaderLen >= pStMsg->iMallocAppHeaderLength) + { + int iFitSize = + rmb_get_fit_size (pStMsg->iAppHeaderLen, MAX_APPHEADER_LENGTH); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "appheader len=%u too large!max_limit=%u\n", + pStMsg->iAppHeaderLen, MAX_APPHEADER_LENGTH); + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return rmb_errno; + } + free (pStMsg->cAppHeader); + pStMsg->cAppHeader = NULL; + pStMsg->cAppHeader = (char *) malloc (iFitSize); + pStMsg->iMallocAppHeaderLength = iFitSize; + } + if (uiBufLen > uiLen) + { + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -2; + } + + //copy AppHeader -- data + memcpy (pStMsg->cAppHeader, p, pStMsg->iAppHeaderLen); + pStMsg->cAppHeader[pStMsg->iAppHeaderLen] = 0; + p += pStMsg->iAppHeaderLen; + + //copy content + memcpy (&pStMsg->iContentLen, p, sizeof (int)); + p += sizeof (int); + + uiBufLen += pStMsg->iContentLen; + if (pStMsg->iContentLen >= pStMsg->iMallocContentLength) + { + int iFitSize = + rmb_get_fit_size (pStMsg->iContentLen, MAX_MSG_CONTENT_SIZE); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "content len=%u too large!max_limit=%u\n", uiLen, + MAX_MSG_CONTENT_SIZE); + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -3; + } + free (pStMsg->cContent); + pStMsg->cContent = NULL; + pStMsg->cContent = (char *) malloc (iFitSize); + pStMsg->iMallocContentLength = iFitSize; + } + + if (uiBufLen > uiLen) + { + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -3; + } + + //copy content + memcpy (pStMsg->cContent, p, pStMsg->iContentLen); + pStMsg->cContent[pStMsg->iContentLen] = 0; + p += pStMsg->iContentLen; + + //copy corrid + memcpy (&pStMsg->iCorrLen, p, sizeof (int)); + p += sizeof (int); + + uiBufLen += pStMsg->iCorrLen; + if (uiBufLen > uiLen) + { + rmb_errno = RMB_ERROR_BUF_2_MSG_FAIL; + return -4; + } + + memcpy (pStMsg->cCorrId, p, pStMsg->iCorrLen); + p += pStMsg->iCorrLen; + + memcpy (&pStMsg->iEventOrService, p, sizeof (int)); + p += sizeof (int); + + memcpy (pStMsg->strTargetDcn, p, sizeof (pStMsg->strTargetDcn)); + p += sizeof (pStMsg->strTargetDcn); + + memcpy (pStMsg->strServiceId, p, sizeof (pStMsg->strServiceId)); + p += sizeof (pStMsg->strServiceId); + + memcpy (pStMsg->strScenarioId, p, sizeof (pStMsg->strScenarioId)); + p += sizeof (pStMsg->strScenarioId); + + //memcpy(pStMsg, &msg, sizeof(StRmbMsg)); + + return 0; +} + +int shift_msg_2_buf (char *cBuf, unsigned int *pLen, const StRmbMsg * pStMsg) +{ + unsigned int uiMsgLen = 0; + uiMsgLen = + 3 * sizeof (char) + sizeof (StSystemHeader) + 2 * sizeof (StDestination) + + 2 * sizeof (unsigned long); + uiMsgLen += + 3 * sizeof (int) + sizeof (StFlow *) + sizeof (pStMsg->strTargetDcn) + + sizeof (pStMsg->strServiceId) + sizeof (pStMsg->strScenarioId) + + sizeof (int); + uiMsgLen += pStMsg->iAppHeaderLen + pStMsg->iContentLen + pStMsg->iCorrLen; + uiMsgLen += sizeof (int); + + char *p = cBuf; + + if (*pLen < uiMsgLen) + { + rmb_errno = RMB_ERROR_MSG_2_BUF_FAIL; + return rmb_errno; + } + + *pLen = uiMsgLen; + + //set msg src + memcpy (p, &pStMsg->iMsgMode, sizeof (int)); + p += sizeof (int); + + //copy cPkgType + *p = pStMsg->cPkgType; + p += sizeof (char); + + //copy cLogicType + *p = pStMsg->cLogicType; + p += sizeof (char); + + //copy cApiType + *p = pStMsg->cApiType; + p += sizeof (char); + + //copy sysheader + memcpy (p, &pStMsg->sysHeader, sizeof (pStMsg->sysHeader)); + p += sizeof (pStMsg->sysHeader); + + //copy dest + memcpy (p, &pStMsg->dest, sizeof (pStMsg->dest)); + p += sizeof (pStMsg->dest); + + //copy replyTo + memcpy (p, &pStMsg->replyTo, sizeof (pStMsg->replyTo)); + p += sizeof (pStMsg->replyTo); + + //copy msgid + memcpy (p, &pStMsg->ulMsgId, sizeof (unsigned long)); + p += sizeof (unsigned long); + + //copy msgLiveTime + memcpy (p, &pStMsg->ulMsgLiveTime, sizeof (unsigned long)); + p += sizeof (unsigned long); + + //copy Appheader + memcpy (p, &pStMsg->iAppHeaderLen, sizeof (int)); + p += sizeof (int); + + memcpy (p, pStMsg->cAppHeader, pStMsg->iAppHeaderLen); + p += pStMsg->iAppHeaderLen; + + //copy content + memcpy (p, &pStMsg->iContentLen, sizeof (int)); + p += sizeof (int); + + memcpy (p, pStMsg->cContent, pStMsg->iContentLen); + p += pStMsg->iContentLen; + + //copy corrid + memcpy (p, &pStMsg->iCorrLen, sizeof (int)); + p += sizeof (int); + + memcpy (p, pStMsg->cCorrId, pStMsg->iCorrLen); + p += pStMsg->iCorrLen; + + memcpy (p, &pStMsg->iEventOrService, sizeof (int)); + p += sizeof (int); + + memcpy (p, pStMsg->strTargetDcn, sizeof (pStMsg->strTargetDcn)); + p += sizeof (pStMsg->strTargetDcn); + + memcpy (p, pStMsg->strServiceId, sizeof (pStMsg->strServiceId)); + p += sizeof (pStMsg->strServiceId); + + memcpy (p, pStMsg->strScenarioId, sizeof (pStMsg->strScenarioId)); + p += sizeof (pStMsg->strScenarioId); + + return 0; +} + +int set_extfields_2_rmb_msg (StRmbMsg * pStMsg, const char *command, int iSeq) +{ + char born_time[32]; + char store_time[32]; + char leave_time[32]; + char arrive_time[32]; + + memset (born_time, 0x00, sizeof (born_time)); + memset (store_time, 0x00, sizeof (store_time)); + memset (leave_time, 0x00, sizeof (leave_time)); + memset (arrive_time, 0x00, sizeof (arrive_time)); + + WEMQJSON *jsonDecoder = NULL; + WEMQJSON *jsonExtField = NULL; + WEMQJSON *property = json_tokener_parse (pStMsg->sysHeader.cProperty); + if (NULL != property) + { + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_BORN_TIME_STR, &jsonDecoder)) + { + const char *tmpTime = json_object_get_string (jsonDecoder); + snprintf (born_time, sizeof (born_time), "%s", tmpTime); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In property, %s is null!", + MSG_BODY_PROPERTY_BORN_TIME_STR); + } + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_STORE_TIME_STR, &jsonDecoder)) + { + const char *tmpTime = json_object_get_string (jsonDecoder); + snprintf (store_time, sizeof (store_time), "%s", tmpTime); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In property, %s is null!", + MSG_BODY_PROPERTY_STORE_TIME_STR); + } + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_LEAVE_TIME_STR, &jsonDecoder)) + { + const char *tmpTime = json_object_get_string (jsonDecoder); + snprintf (leave_time, sizeof (leave_time), "%s", tmpTime); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In property, %s is null!", + MSG_BODY_PROPERTY_LEAVE_TIME_STR); + } + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_ARRIVE_TIME_STR, &jsonDecoder)) + { + const char *tmpTime = json_object_get_string (jsonDecoder); + snprintf (arrive_time, sizeof (arrive_time), "%s", tmpTime); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In property, %s is null!", + MSG_BODY_PROPERTY_ARRIVE_TIME_STR); + } + } + jsonExtField = json_tokener_parse (pStMsg->sysHeader.cExtFields); + if (jsonExtField == NULL) + { + jsonExtField = json_object_new_object (); + } + + if (strcmp (command, REQUEST_TO_CLIENT) == 0 + || strcmp (command, ASYNC_MESSAGE_TO_CLIENT) == 0 + || strcmp (command, BROADCAST_MESSAGE_TO_CLIENT) == 0) + { + json_object_object_add (jsonExtField, REQ_BORN_TIMESTAMP, + json_object_new_string (born_time)); + json_object_object_add (jsonExtField, REQ_STORE_TIMESTAMP, + json_object_new_string (store_time)); + json_object_object_add (jsonExtField, REQ_LEAVE_TIMESTAMP, + json_object_new_string (leave_time)); + json_object_object_add (jsonExtField, REQ_ARRIVE_TIMESTAMP, + json_object_new_string (arrive_time)); + json_object_object_add (jsonExtField, MSG_BODY_SYSTEM_ACK_SEQ, + json_object_new_int (iSeq)); + } + else if (strcmp (command, RESPONSE_TO_CLIENT) == 0) + { + json_object_object_add (jsonExtField, RSP_BORN_TIMESTAMP, + json_object_new_string (born_time)); + json_object_object_add (jsonExtField, RSP_STORE_TIMESTAMP, + json_object_new_string (store_time)); + json_object_object_add (jsonExtField, RSP_LEAVE_TIMESTAMP, + json_object_new_string (leave_time)); + json_object_object_add (jsonExtField, RSP_ARRIVE_TIMESTAMP, + json_object_new_string (arrive_time)); + } + + const char *extFields = json_object_get_string (jsonExtField); + if (extFields != NULL) + { + int len = (int) strlen (extFields); + if (len >= RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN) + { + LOGRMB (RMB_LOG_ERROR, "systemHeader len=%d too large!max_limit=%d: %s", + len, RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN, extFields); + } + else + { + snprintf (pStMsg->sysHeader.cExtFields, + sizeof (pStMsg->sysHeader.cExtFields), "%s", extFields); + } + } + json_object_put (property); + json_object_put (jsonExtField); + return 0; +} + +static WEMQJSON *generate_destination_from_topic (StRmbMsg * pStMsg, + char *pTopic) +{ + + char cDestName[200]; + char strTargetDcn[10]; + char strServiceId[10]; + char strScenarioId[5]; + + //判断分隔符数量是否正确 + int i = 0; + char *ptopic = pTopic; + char *pTemp = NULL; + do + { + pTemp = strchr (ptopic, '-'); + if (pTemp == NULL) + { + break; + } + i++; + ptopic = pTemp + 1; + } + while (ptopic != NULL); + + if (i != 4) + { + if (strstr (pTopic, "reply-topic") == NULL) + { + LOGRMB (RMB_LOG_WARN, "topic:%s formatting is not conformed!", pTopic); + return NULL; + } + } + + WEMQJSON *jsonDest = json_object_new_object (); + if (jsonDest == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return NULL; + } + + memset (cDestName, 0x00, sizeof (cDestName)); + snprintf (cDestName, sizeof (pStMsg->dest.cDestName), "%s", pTopic); + + for (i = 0; i < strlen (cDestName) && cDestName[i] != '\0'; i++) + { + if (cDestName[i] == '-') + { + cDestName[i] = '/'; + } + } + json_object_object_add (jsonDest, MSG_BODY_DEST_NAME_STR, + json_object_new_string (cDestName)); + + pTemp = strrchr (cDestName, '/'); + *pTemp = '\0'; + //copy ScenarioId + pTemp = strrchr (cDestName, '/'); + if (pTemp == NULL) + { + return NULL; + } + snprintf (strScenarioId, sizeof (strScenarioId), "%s", pTemp + 1); + *pTemp = '\0'; + + //copy ServiceId + pTemp = strrchr (cDestName, '/'); + if (pTemp == NULL) + { + return NULL; + } + snprintf (strServiceId, sizeof (strServiceId), "%s", pTemp + 1); + *pTemp = '\0'; + + pTemp = strrchr (cDestName, '/'); + if (pTemp == NULL) + { + return NULL; + } + *pTemp = '\0'; + //copy TargetDcn + snprintf (strTargetDcn, sizeof (strTargetDcn), "%s", cDestName); + + json_object_object_add (jsonDest, MSG_BODY_DEST_TYPE_STR, + json_object_new_string ("se")); + json_object_object_add (jsonDest, MSG_BODY_DEST_SORE_STR, + json_object_new_string (strServiceId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_SCENARIO_STR, + json_object_new_string (strScenarioId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_DCN_STR, + json_object_new_string (strTargetDcn)); + json_object_object_add (jsonDest, MSG_BODY_DEST_ORGID_STR, + json_object_new_string (pStMsg->sysHeader.cOrgId)); + + return jsonDest; +} + +int trans_json_2_rmb_msg (StRmbMsg * pStMsg, const char *bodyJson, + const char *command) +{ + if (pStMsg == NULL || bodyJson == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStMsg or bodyJson is null"); + return -1; + } + + rmb_msg_clear (pStMsg); + + pStMsg->cApiType = C_TYPE_WEMQ; + + WEMQJSON *systemHeader = NULL; + WEMQJSON *dest = NULL; + WEMQJSON *jsonDecoder = NULL; + WEMQJSON *property = NULL; + WEMQJSON *jsonByteBody = NULL; + + WEMQJSON *jsonBody = json_tokener_parse (bodyJson); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_tokener_parse failed!,buf is:%s", bodyJson); + return -1; + } + if (!json_object_object_get_ex + (jsonBody, MSG_BODY_BYTE_BODY_JSON, &jsonByteBody)) + { + LOGRMB (RMB_LOG_ERROR, "body json no byte body!"); + return -2; + } //byte body json + + if (!json_object_object_get_ex + (jsonBody, MSG_BODY_PROPERTY_JSON, &property)) + { + LOGRMB (RMB_LOG_ERROR, "body json no properties!"); + return -2; + } //property json + jsonByteBody = json_tokener_parse (json_object_get_string (jsonByteBody)); + if (!json_object_object_get_ex + (jsonByteBody, MSG_BODY_BYTE_BODY_SYSTEM_HEADER_CONTENT_JSON, + &systemHeader)) + { + LOGRMB (RMB_LOG_ERROR, "byte body json no system header content!"); + return -2; + } //system header json + systemHeader = json_tokener_parse (json_object_get_string (systemHeader)); + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_BIZ_STR, &jsonDecoder)) + { + const char *bizNo = json_object_get_string (jsonDecoder); + if (bizNo != NULL) + { + snprintf (pStMsg->sysHeader.cBizSeqNo, + sizeof (pStMsg->sysHeader.cBizSeqNo), "%s", bizNo); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_BIZ_STR); + } + } //system header bizno + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_SEQNO_STR, &jsonDecoder)) + { + const char *seqNo = json_object_get_string (jsonDecoder); + if (seqNo != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerSeqNo, + sizeof (pStMsg->sysHeader.cConsumerSeqNo), "%s", seqNo); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_SEQNO_STR); + } + } //system header seqNo + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_SVRID_STR, &jsonDecoder)) + { + const char *svrId = json_object_get_string (jsonDecoder); + if (svrId != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerSvrId, + sizeof (pStMsg->sysHeader.cConsumerSvrId), "%s", svrId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_SVRID_STR); + } + } //system header svrId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_ORGSYS_STR, &jsonDecoder)) + { + const char *orgId = json_object_get_string (jsonDecoder); + if (orgId != NULL) + { + snprintf (pStMsg->sysHeader.cOrgSysId, + sizeof (pStMsg->sysHeader.cOrgSysId), "%s", orgId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_ORGSYS_STR); + } + } //system header orgId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_CSMID_STR, &jsonDecoder)) + { + const char *csmId = json_object_get_string (jsonDecoder); + if (csmId != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerSysId, + sizeof (pStMsg->sysHeader.cConsumerSysId), "%s", csmId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_CSMID_STR); + } + } //system header csmId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_TIME_LINT, &jsonDecoder)) + { + pStMsg->sysHeader.ulTranTimeStamp = json_object_get_int64 (jsonDecoder); + } //system header transTime + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_CSMDCN_STR, &jsonDecoder)) + { + const char *csmDcn = json_object_get_string (jsonDecoder); + if (csmDcn != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerDcn, + sizeof (pStMsg->sysHeader.cConsumerDcn), "%s", csmDcn); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_CSMDCN_STR); + } + } //system header csmDcn + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_ORGSVR_STR, &jsonDecoder)) + { + const char *orgSysId = json_object_get_string (jsonDecoder); + if (orgSysId != NULL) + { + snprintf (pStMsg->sysHeader.cOrgSvrId, + sizeof (pStMsg->sysHeader.cOrgSvrId), "%s", orgSysId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_ORGSVR_STR); + } + } //system header orgSysId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_ORGID_STR, &jsonDecoder)) + { + const char *cOrgId = json_object_get_string (jsonDecoder); + if (cOrgId != NULL) + { + snprintf (pStMsg->sysHeader.cOrgId, sizeof (pStMsg->sysHeader.cOrgId), + "%s", cOrgId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_ORGID_STR); + } + } //system header cOrgId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_UNIID_STR, &jsonDecoder)) + { + const char *cUniqueId = json_object_get_string (jsonDecoder); + if (cUniqueId != NULL) + { + snprintf (pStMsg->sysHeader.cUniqueId, + sizeof (pStMsg->sysHeader.cUniqueId), "%s", cUniqueId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_UNIID_STR); + } + } //system header cUniqueId + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_CONLEN_INT, &jsonDecoder)) + { + pStMsg->sysHeader.iContentLength = json_object_get_int (jsonDecoder); + } //system header iContentLength + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_SENDTIME_LINT, &jsonDecoder)) + { + pStMsg->sysHeader.ulSendTime = json_object_get_int64 (jsonDecoder); + } //system header ulSendTime + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_RECVTIME_LINT, &jsonDecoder)) + { + pStMsg->sysHeader.ulReceiveTime = json_object_get_int64 (jsonDecoder); + } + if (pStMsg->sysHeader.ulReceiveTime == 0) + { + GetRmbNowLongTime (); + pStMsg->sysHeader.ulReceiveTime = pRmbStConfig->ulNowTtime; + } + //system header ulReceiveTime + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_REPLYTIME_LINT, &jsonDecoder)) + { + pStMsg->sysHeader.ulReplyTime = json_object_get_int64 (jsonDecoder); + } //system header ulReplyTime + + if (json_object_object_get_ex + (jsonByteBody, MSG_BODY_BYTE_BODY_APPHEADER_NAME_STR, &jsonDecoder)) + { + const char *pAppheaderClass = json_object_get_string (jsonDecoder); + if (pAppheaderClass != NULL) + { + snprintf (pStMsg->sysHeader.cAppHeaderClass, + sizeof (pStMsg->sysHeader.cAppHeaderClass), "%s", + pAppheaderClass); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_BYTE_BODY_APPHEADER_NAME_STR); + } + } // system header cAppHeaderClass + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_VER_STR, &jsonDecoder)) + { + const char *pConsumerSysVersion = json_object_get_string (jsonDecoder); + if (pConsumerSysVersion != NULL) + { + snprintf (pStMsg->sysHeader.cConsumerSysVersion, + sizeof (pStMsg->sysHeader.cConsumerSysVersion), "%s", + pConsumerSysVersion); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_VER_STR); + } + } + //system consumerSysVersion + + const char *cProperty = json_object_get_string (property); + if (cProperty != NULL) + { + int len = (int) strlen (property); + if (len >= RMB_SYSTEMHEADER_PROPERTY_MAX_LEN) + { + LOGRMB (RMB_LOG_ERROR, "property len=%d too large!max_limit=%d: %s", + len, RMB_SYSTEMHEADER_PROPERTY_MAX_LEN, cProperty); + } + else + { + snprintf (pStMsg->sysHeader.cProperty, + sizeof (pStMsg->sysHeader.cProperty), "%s", cProperty); + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_PROPERTY_JSON); + } + + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_EXTFIELDS_STR, &jsonDecoder)) + { + const char *extFields = json_object_get_string (jsonDecoder); + if (extFields != NULL) + { + int len = (int) strlen (extFields); + if (len >= RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN) + { + LOGRMB (RMB_LOG_ERROR, + "systemHeader len=%d too large!max_limit=%d: %s", len, + RMB_SYSTEMHEADER_EXTFIELDS_MAX_LEN, extFields); + } + else + { + snprintf (pStMsg->sysHeader.cExtFields, + sizeof (pStMsg->sysHeader.cExtFields), "%s", extFields); + } + if (strstr (extFields, "\"IS_DYED_MSG\": \"true\"") != NULL) + { + LOGRMB (RMB_LOG_DEBUG, "trans msg, extfield is %s", extFields); + strcpy (pStMsg->isDyedMsg, "true"); + } + else + { + strcpy (pStMsg->isDyedMsg, "false"); + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "In systemHeader, %s is null!", + MSG_BODY_SYSTEM_EXTFIELDS_STR); + } + + } //system header extFields + + if (json_object_object_get_ex + (jsonByteBody, MSG_BODY_BYTE_BODY_APPHEADER_CONTENT_JSON, &jsonDecoder)) + { + const char *appHeader = json_object_get_string (jsonDecoder); + if (appHeader != NULL) + { + //get appHeader len + unsigned int uiAppHeaderLen = json_object_get_string_len (jsonDecoder); + if (uiAppHeaderLen >= pStMsg->iMallocAppHeaderLength) + { + int iFitSize = + rmb_get_fit_size (uiAppHeaderLen, MAX_APPHEADER_LENGTH); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "appHeader len=%d too large!max_limit=%u", + uiAppHeaderLen, MAX_APPHEADER_LENGTH); + return -1; + } + free (pStMsg->cAppHeader); + pStMsg->cAppHeader = NULL; + pStMsg->cAppHeader = (char *) malloc (iFitSize); + pStMsg->iMallocAppHeaderLength = iFitSize; + } + pStMsg->iAppHeaderLen = uiAppHeaderLen; + memcpy (pStMsg->cAppHeader, json_object_get_string (jsonDecoder), + uiAppHeaderLen); + pStMsg->cAppHeader[pStMsg->iAppHeaderLen] = '\0'; + } + else + { + LOGRMB (RMB_LOG_ERROR, "In body, %s is null!", MSG_BODY_APP_JSON); + } + } //appHeader + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_TTL_INT, &jsonDecoder)) + { + pStMsg->ulMsgLiveTime = json_object_get_int64 (jsonDecoder); + } //header ulMsgLiveTime + + //if (json_object_object_get_ex(jsonBody, MSG_BODY_TOPIC_STR, &jsonDecoder)) + //{ + // const char *topic = json_object_get_string(jsonDecoder); + + // dest = generate_destination_from_topic(pStMsg,topic); + if (json_object_object_get_ex (jsonByteBody, MSG_BODY_DEST_JSON, &dest)) + { + dest = json_tokener_parse (json_object_get_string (dest)); + } + else + { + if (json_object_object_get_ex + (jsonBody, MSG_BODY_TOPIC_STR, &jsonDecoder)) + { + const char *topic = json_object_get_string (jsonDecoder); + dest = generate_destination_from_topic (pStMsg, topic); + } + + } + if (NULL != dest) + { + if (json_object_object_get_ex + (dest, MSG_BODY_DEST_NAME_STR, &jsonDecoder)) + { + //get name + const char *destTmp = json_object_get_string (jsonDecoder); + if (destTmp != NULL) + { + snprintf (pStMsg->dest.cDestName, sizeof (pStMsg->dest.cDestName), + "%s", destTmp); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null", + MSG_BODY_DEST_NAME_STR); + } + } //get name + + if (json_object_object_get_ex + (dest, MSG_BODY_DEST_SORE_STR, &jsonDecoder)) + { + const char *pServiceId = json_object_get_string (jsonDecoder); + if (pServiceId != NULL) + { + snprintf (pStMsg->strServiceId, sizeof (pStMsg->strServiceId), "%s", + pServiceId); + pStMsg->iEventOrService = + (*(pServiceId + 3) == '0') ? RMB_SERVICE_CALL : RMB_EVENT_CALL; + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null", + MSG_BODY_DEST_SORE_STR); + } + } //get serviceOrEventId + + if (json_object_object_get_ex + (dest, MSG_BODY_DEST_SCENARIO_STR, &jsonDecoder)) + { + const char *pScenarioId = json_object_get_string (jsonDecoder); + if (pScenarioId != NULL) + { + snprintf (pStMsg->strScenarioId, sizeof (pStMsg->strScenarioId), "%s", + pScenarioId); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null!", + MSG_BODY_DEST_SCENARIO_STR); + } + } //get scenario + + if (json_object_object_get_ex (dest, MSG_BODY_DEST_DCN_STR, &jsonDecoder)) + { + const char *pDcn = json_object_get_string (jsonDecoder); + if (pDcn != NULL) + { + snprintf (pStMsg->strTargetDcn, sizeof (pStMsg->strTargetDcn), "%s", + pDcn); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null!", + MSG_BODY_DEST_DCN_STR); + } + } //get dcn + + if (json_object_object_get_ex + (dest, MSG_BODY_DEST_ORGID_STR, &jsonDecoder)) + { + const char *pOrganization = json_object_get_string (jsonDecoder); + if (pOrganization != NULL) + { + snprintf (pStMsg->strTargetOrgId, sizeof (pStMsg->strTargetOrgId), + "%s", pOrganization); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In destination, %s is null", + MSG_BODY_DEST_ORGID_STR); + } + } //get organization + //header dest + } + //topic + + if (json_object_object_get_ex + (property, MSG_BODY_PROPERTY_REPLYTO_STR, &jsonDecoder)) + { + const char *replyTo = json_object_get_string (jsonDecoder); + if (replyTo != NULL) + { + snprintf (pStMsg->replyTo.cDestName, sizeof (pStMsg->replyTo.cDestName), + "%s", replyTo); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In bodyjson, %s is null", MSG_BODY_REPLYTO_STR); + } + } //header replyTo + + if (json_object_object_get_ex + (jsonByteBody, MSG_BODY_BYTE_BODY_CONTENT_STR, &jsonDecoder)) + { + const char *cContent = json_object_get_string (jsonDecoder); + if (cContent != NULL) + { +// pStMsg->iContentLen = strlen(cContent); + pStMsg->iContentLen = json_object_get_string_len (jsonDecoder); + LOGRMB (RMB_LOG_DEBUG, "get content len:%d", pStMsg->iContentLen); + if (pStMsg->iContentLen >= pStMsg->iMallocContentLength) + { + int iFitSize = + rmb_get_fit_size (pStMsg->iContentLen, MAX_MSG_CONTENT_SIZE); + if (iFitSize < 0) + { + LOGRMB (RMB_LOG_ERROR, "content len=%d too large!max_limit=%u", + pStMsg->iContentLen, MAX_MSG_CONTENT_SIZE); + return -1; + } + free (pStMsg->cContent); + pStMsg->cContent = NULL; + pStMsg->cContent = (char *) malloc (iFitSize); + pStMsg->iMallocContentLength = iFitSize; + } + //strncpy(pStMsg->cContent, cContent, pStMsg->iContentLen); + memcpy (pStMsg->cContent, cContent, pStMsg->iContentLen); + pStMsg->cContent[pStMsg->iContentLen] = '\0'; + LOGRMB (RMB_LOG_DEBUG, "get content:%d - %s", pStMsg->iContentLen, + pStMsg->cContent); + } + else + { + LOGRMB (RMB_LOG_ERROR, "In bodyjson, %s is null", MSG_BODY_CONTENT_STR); + } + } //header cContent + + json_object_put (dest); + json_object_put (systemHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return 0; +} + +int rmb_msg_print_v (StRmbMsg * pRmbMsg) +{ + LOGRMB (RMB_LOG_DEBUG, + "[type=%s,send=%lu,rev=%lu,dest=%s,bizSeqNo=%s,cSeqNo=%s,replyTo=%s,len=%d,content=%s]", + (int) pRmbMsg->cLogicType <= + 6 ? strLogicType[(int) (pRmbMsg->cLogicType)] : "null", + pRmbMsg->sysHeader.ulSendTime, pRmbMsg->sysHeader.ulReceiveTime, + pRmbMsg->dest.cDestName, pRmbMsg->sysHeader.cBizSeqNo, + pRmbMsg->sysHeader.cConsumerSeqNo, pRmbMsg->replyTo.cDestName, + pRmbMsg->iContentLen, pRmbMsg->cContent); + return 0; +} + +const char *rmb_msg_print (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg->cLogicType == REQ_PKG_IN + || pRmbMsg->cLogicType == EVENT_PKG_IN) + { + snprintf (pRmbMsg->strLogBuf, sizeof (pRmbMsg->strLogBuf) - 1, + "[type=%s,send=%lu,rev=%lu,dest=%s,bizSeqNo=%s,cSeqNo=%s,replyTo=%s,len=%d,content=%s]", + (int) pRmbMsg->cLogicType <= + 6 ? strLogicType[(int) (pRmbMsg->cLogicType)] : "null", + pRmbMsg->sysHeader.ulSendTime, pRmbMsg->sysHeader.ulReceiveTime, + pRmbMsg->dest.cDestName, pRmbMsg->sysHeader.cBizSeqNo, + pRmbMsg->sysHeader.cConsumerSeqNo, pRmbMsg->replyTo.cDestName, + pRmbMsg->iContentLen, pRmbMsg->cContent); + } + else if (pRmbMsg->cLogicType == RSP_PKG_IN + || pRmbMsg->cLogicType == RSP_PKG_OUT) + { + snprintf (pRmbMsg->strLogBuf, sizeof (pRmbMsg->strLogBuf) - 1, + "[type=%s,send=%lu,rev=%lu,reply=%lu,dest=%s,bizSeqNo=%s,cSeqNo=%s,replyTo=%s,len=%d,content=%s]", + (int) pRmbMsg->cLogicType <= + 6 ? strLogicType[(int) (pRmbMsg->cLogicType)] : "null", + pRmbMsg->sysHeader.ulSendTime, pRmbMsg->sysHeader.ulReceiveTime, + pRmbMsg->sysHeader.ulReplyTime, pRmbMsg->dest.cDestName, + pRmbMsg->sysHeader.cBizSeqNo, pRmbMsg->sysHeader.cConsumerSeqNo, + pRmbMsg->replyTo.cDestName, pRmbMsg->iContentLen, + pRmbMsg->cContent); + } + else + { + snprintf (pRmbMsg->strLogBuf, sizeof (pRmbMsg->strLogBuf) - 1, + "[type=%s,send=%lu,dest=%s,bizSeqNo=%s,cSeqNo=%s,replyTo=%s,len=%d,content=%s]", + (int) pRmbMsg->cLogicType <= + 6 ? strLogicType[(int) (pRmbMsg->cLogicType)] : "null", + pRmbMsg->sysHeader.ulSendTime, pRmbMsg->dest.cDestName, + pRmbMsg->sysHeader.cBizSeqNo, pRmbMsg->sysHeader.cConsumerSeqNo, + pRmbMsg->replyTo.cDestName, pRmbMsg->iContentLen, + pRmbMsg->cContent); + } + + pRmbMsg->strLogBuf[sizeof (pRmbMsg->strLogBuf) - 1] = 0; + return pRmbMsg->strLogBuf; +} + +//消息初始化 +StRmbMsg *rmb_msg_malloc () +{ + StRmbMsg *rmbMsg = (StRmbMsg *) malloc (sizeof (StRmbMsg)); + if (rmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for rmbMsg error!\n"); + return NULL; + } + memset (rmbMsg, 0, sizeof (StRmbMsg)); + + rmbMsg->cContent = (char *) malloc (i1KB); + if (rmbMsg->cContent == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for rmbMsg->cContent error!\n"); + free (rmbMsg); + rmbMsg = NULL; + return NULL; + } + memset (rmbMsg->cContent, 0x00, sizeof (char) * i1KB); + rmbMsg->iMallocContentLength = i1KB; + + rmbMsg->cAppHeader = (char *) malloc (i1KB); + if (rmbMsg->cAppHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for rmbMsg->cAppHeader error!\n"); + free (rmbMsg->cContent); + rmbMsg->cContent = NULL; + free (rmbMsg); + rmbMsg = NULL; + return NULL; + } + memset (rmbMsg->cAppHeader, 0x00, sizeof (char) * i1KB); + rmbMsg->iMallocAppHeaderLength = i1KB; + + return rmbMsg; +} + +//消息释放 +int rmb_msg_free (StRmbMsg * pRmbMsg) +{ + if (pRmbMsg == NULL) + { + return 0; + } + if (pRmbMsg->cContent != NULL && pRmbMsg->iMallocContentLength != 0) + { + free (pRmbMsg->cContent); + pRmbMsg->cContent = NULL; + } + if (pRmbMsg->cAppHeader != NULL && pRmbMsg->iMallocAppHeaderLength != 0) + { + free (pRmbMsg->cAppHeader); + pRmbMsg->cAppHeader = NULL; + } + + free (pRmbMsg); + return 0; +} + +int rmb_msg_random_uuid (char *puuid, size_t size) +{ + char cUniqueIdEx[50] = { 0 }; + uuid_t uuidout; + uuid_generate_random (uuidout); + uuid_unparse (uuidout, cUniqueIdEx); + snprintf (puuid, size, "%s", cUniqueIdEx); + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_pub.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_pub.c new file mode 100644 index 0000000000..784ce498cc --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_pub.c @@ -0,0 +1,2453 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include "common.h" +#include "rmb_pub.h" +#include "rmb_context.h" +#include "rmb_udp.h" +#include "rmb_common.h" +#include "rmb_errno.h" +#include "wemq_thread.h" + +static int g_iSendReq = 0; +static unsigned long g_iSendReqForEvent = 100000000; +static StRmbPub *pRmbGlobalPub; + +unsigned int g_uiSendMsgSeq = 0; +unsigned int g_uiRecvMsgSeq = 0; +unsigned int DEFAULT_WINDOW_SIZE = 100; + +typedef struct gsl_err +{ + char result; + const char *err_msg; +} gsl_err; + +gsl_err gsl_error[] = { + {0x01, NULL}, + {0x11, "query ckv null"}, + {0x21, "chvvalue.orgid_list_size() = 0"}, + {0x31, "orgid for query rules is null"}, + {0x41, "no available rules for service"}, + {0x51, "ckvvalue.org.dcn_list_size() = 0"}, + {0x61, "target dcn is null according to query rules for event"}, + {0x71, NULL}, + {0x81, NULL}, + {0x91, NULL}, + {0xA1, NULL}, + {0xB1, NULL}, + {0xC1, NULL}, + {0xD1, NULL}, + {0xE1, NULL}, + {0xF1, NULL}, + {0x02, NULL}, + {0x12, + "CommonOrgid points to SingleOrgid, service cannot be deployed in more than one ADM or C-DCN"}, + {0x22, + "CommonOrgid points to SingleOrgid, service cannot be found in either ADM or C-DCN"}, + {0x32, + "public service id is deployed in multiple regions causing conflicts"}, + {0x42, + "service is poly-active in one area(R-DCN/C-DCN/ADM/Common), but dcn matching IDC of clientDcn not found"}, + {0x52, + "event subscriptors belong to one area(CS/DMZ/ECN), but dcn matching IDC of clientDcn not found"}, + {0x62, NULL}, + {0x72, NULL}, + {0x82, NULL}, + {0x92, NULL}, + {0xA2, NULL}, + {0xB2, NULL}, + {0xC2, NULL}, + {0xD2, NULL}, + {0xE2, NULL}, + {0xF2, NULL}, + {0x03, NULL}, + {0x13, "DecodeBuf error or ParseFromString error"}, + {0x23, "query ckv error"}, + {0x33, NULL}, + {0x43, NULL}, + {0x53, NULL}, + {0x63, NULL}, + {0x73, NULL}, + {0x83, NULL}, + {0x93, NULL}, + {0xA3, NULL}, + {0xB3, NULL}, + {0xC3, NULL}, + {0xD3, NULL}, + {0xE3, NULL}, + {0xF3, NULL} +}; + +//#define TCP_BUF_SIZE 5<<01 +static int rmb_pub_encode_header_for_wemq (unsigned int uiCmd, + StWemqThreadMsg * ptThreadMsg, + StRmbMsg * ptSendMsg) +{ + if (ptThreadMsg == NULL || ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptThreadMsg is null or ptSendMsg is null"); + return -1; + } + + switch (uiCmd) + { + case THREAD_MSG_CMD_SEND_MSG: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_MSG; + + WEMQJSON *jsonHeader = json_object_new_object (); + + // ptSendMsg->strServiceId[3] == '3' 多播使用ASYNC_MESSAGE_TO_SERVER + if (ptSendMsg->strServiceId[3] == '4') + { + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string + (BROADCAST_MESSAGE_TO_SERVER)); + } + else + { + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string + (ASYNC_MESSAGE_TO_SERVER)); + } + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (++g_iSendReqForEvent)); + LOGRMB (RMB_LOG_DEBUG, "put seq:%ld in pkg", g_iSendReqForEvent); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", + ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + return 0; + } + case THREAD_MSG_CMD_SEND_REQUEST: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_REQUEST; + + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (REQUEST_TO_SERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (g_iSendReq++)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", + ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed\n"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + json_object_put (jsonHeader); + return 0; + } + case THREAD_MSG_CMD_SEND_REQUEST_ASYNC: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_REQUEST_ASYNC; + + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (REQUEST_TO_SERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (g_iSendReq++)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", + ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed\n"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + json_object_put (jsonHeader); + return 0; + } + case THREAD_MSG_CMD_SEND_REPLY: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_REPLY; + + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (RESPONSE_TO_SERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (g_iSendReq++)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + //LOGRMB(RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed\n"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + return 0; + } + case THREAD_MSG_CMD_SEND_MSG_ACK: + { + ptThreadMsg->m_iCmd = THREAD_MSG_CMD_SEND_MSG_ACK; + + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (MSG_ACK)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (g_iSendReq++)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg header failed"); + json_object_put (jsonHeader); + return -1; + } + ptThreadMsg->m_iHeaderLen = strlen (header_str); + + //LOGRMB(RMB_LOG_DEBUG, "Get thread msg header succ, len=%d,%s\n", ptThreadMsg->m_iHeaderLen, header_str); + ptThreadMsg->m_pHeader = + (char *) malloc ((ptThreadMsg->m_iHeaderLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pHeader failed\n"); + json_object_put (jsonHeader); + return -2; + } + memcpy (ptThreadMsg->m_pHeader, header_str, ptThreadMsg->m_iHeaderLen); + ptThreadMsg->m_pHeader[ptThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + return 0; + } + default: + LOGRMB (RMB_LOG_ERROR, "unknown cmd:%u", uiCmd); + return -1; + } + + return 0; +} + +static WEMQJSON *rmb_pub_encode_system_header_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg) +{ + if (ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptSendMsg is null"); + return NULL; + } + + WEMQJSON *jsonSystem = json_object_new_object (); + + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_BIZ_STR, + json_object_new_string (ptSendMsg->sysHeader. + cBizSeqNo)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_SEQNO_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSeqNo)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_SVRID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSvrId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_ORGSYS_STR, + json_object_new_string (ptSendMsg->sysHeader. + cOrgSysId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_CSMID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSysId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_TIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulTranTimeStamp)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_CSMDCN_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerDcn)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_ORGSVR_STR, + json_object_new_string (ptSendMsg->sysHeader. + cOrgSvrId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_ORGID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cOrgId)); + //发送消息时,version为consumerSysVersion,且必须为1.0.0 + //json_object_object_add(jsonSystem, MSG_BODY_SYSTEM_VER_STR, json_object_new_string("weq_c_1_0_0")); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_VER_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSysVersion)); + //add rmb api version + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_API_VERSION, + json_object_new_string (RMBVERSION)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_UNIID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cUniqueId)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_CONLEN_INT, + json_object_new_int (ptSendMsg->sysHeader. + iContentLength)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_MSGTYPE_INT, + json_object_new_int (1)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_RECVTYPE_INT, + json_object_new_int (1)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_SENDTIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulSendTime)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_RECVTIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulReceiveTime)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_REPLYTIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulReplyTime)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_REPLYRECEIVETIME_LINT, + json_object_new_int64 (ptSendMsg->sysHeader. + ulReplyReceiveTime)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_APITYPE_INT, + json_object_new_int (ptSendMsg->cApiType)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_LOGICTYPE_INT, + json_object_new_int ((int32_t) ptSendMsg-> + cLogicType)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_SOCOID_STR, + json_object_new_string ("#C")); + + if (uiCmd == THREAD_MSG_CMD_SEND_REPLY || uiCmd == THREAD_MSG_CMD_RECV_MSG_ACK || uiCmd == THREAD_MSG_CMD_SEND_MSG_ACK) //一般发回包时候、单播回ack,需要rsp_ip + { + WEMQJSON *extFields = + json_tokener_parse (ptSendMsg->sysHeader.cExtFields); + if (extFields == NULL) + { + extFields = json_object_new_object (); + } + json_object_object_add (extFields, MSG_BODY_SYSTEM_RSP_IP, + json_object_new_string (pRmbStConfig->cHostIp)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_RSP_SYS, + json_object_new_string (pRmbStConfig-> + cConsumerSysId)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_RSP_DCN, + json_object_new_string (pRmbStConfig-> + cConsumerDcn)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_RSP_IDC, + json_object_new_string (pRmbStConfig->cRegion)); + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_EXTFIELDS_STR, + extFields); + const char *systemStr = json_object_get_string (jsonSystem); + WEMQJSON *jsonSystemHeader = json_tokener_parse (systemStr); + json_object_put (jsonSystem); + return jsonSystemHeader; + } + else //发包时候 + { + WEMQJSON *extFields = + json_tokener_parse (ptSendMsg->sysHeader.cExtFields); + if (extFields == NULL) + { + extFields = json_object_new_object (); + } + json_object_object_add (extFields, MSG_BODY_SYSTEM_REQ_IP, + json_object_new_string (pRmbStConfig->cHostIp)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_REQ_SYS, + json_object_new_string (pRmbStConfig-> + cConsumerSysId)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_REQ_DCN, + json_object_new_string (pRmbStConfig-> + cConsumerDcn)); + json_object_object_add (extFields, MSG_BODY_SYSTEM_REQ_IDC, + json_object_new_string (pRmbStConfig->cRegion)); + if (strcmp (ptSendMsg->isDyedMsg, "true") == 0) + { + json_object_object_add (extFields, IS_DYED_MSG, + json_object_new_string ("true")); + } + json_object_object_add (jsonSystem, MSG_BODY_SYSTEM_EXTFIELDS_STR, + extFields); + const char *systemStr = json_object_get_string (jsonSystem); + WEMQJSON *jsonSystemHeader = json_tokener_parse (systemStr); + json_object_put (jsonSystem); + return jsonSystemHeader; + } +} + +/** + * set destination proto, like: + * "destination" : { + * "name" : "A00/s/10000000/01/0", + * "type" : "se", + * "serviceOrEventId" : "10000000", + * "scenario" : "01", + * "dcnNo" : "A00", -- not support 000 + * "organizationId" : "99996", + * "organizationIdInputFlag" : 0, + * } + * 其中,type固定为"se",wemq java历史遗留问题 + */ +static WEMQJSON *rmb_pub_encode_body_dest_for_wemq (StRmbMsg * ptSendMsg) +{ + if (ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptSendMsg is null"); + return NULL; + } + + WEMQJSON *jsonDest = json_object_new_object (); + if (jsonDest == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return NULL; + } + + json_object_object_add (jsonDest, MSG_BODY_DEST_NAME_STR, + json_object_new_string (ptSendMsg->dest.cDestName)); + json_object_object_add (jsonDest, MSG_BODY_DEST_TYPE_STR, + json_object_new_string ("se")); + json_object_object_add (jsonDest, MSG_BODY_DEST_SORE_STR, + json_object_new_string (ptSendMsg->strServiceId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_SCENARIO_STR, + json_object_new_string (ptSendMsg->strScenarioId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_DCN_STR, + json_object_new_string (ptSendMsg->strTargetDcn)); + json_object_object_add (jsonDest, MSG_BODY_DEST_ANY_DCN_STR, + json_object_new_boolean (0)); + + json_object_object_add (jsonDest, MSG_BODY_DEST_ORGID_STR, + json_object_new_string (ptSendMsg->strTargetOrgId)); + json_object_object_add (jsonDest, MSG_BODY_DEST_ORGFLAG_INT, + json_object_new_int (ptSendMsg->iFLagForOrgId)); + + return jsonDest; +} + +WEMQJSON *rmb_pub_encode_property_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg) +{ + if (ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptSendMsg is null"); + return NULL; + } + + WEMQJSON *jsonProperty = NULL; + + if (uiCmd == THREAD_MSG_CMD_SEND_REPLY + || uiCmd == THREAD_MSG_CMD_RECV_MSG_ACK + || uiCmd == THREAD_MSG_CMD_SEND_MSG_ACK) + { + jsonProperty = json_tokener_parse (ptSendMsg->sysHeader.cProperty); + if (jsonProperty == NULL) + { + jsonProperty = json_object_new_object (); + } + } + else + { + jsonProperty = json_object_new_object (); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_REPLYTO_STR, + json_object_new_string (ptSendMsg->replyTo. + cDestName)); + json_object_object_add (jsonProperty, + MSG_BODY_PROPERTY_RR_REQUEST_UNIQ_ID_STR, + json_object_new_string (ptSendMsg->sysHeader. + cUniqueId)); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_KEYS_STR, + json_object_new_string (ptSendMsg->sysHeader. + cConsumerSeqNo)); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_MSG_TYPE_STR, + json_object_new_string ("persistent")); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_TTL_INT, + json_object_new_int64 (ptSendMsg->ulMsgLiveTime)); + json_object_object_add (jsonProperty, MSG_BODY_PROPERTY_SEQ_STR, + json_object_new_string (ptSendMsg->sysHeader. + cBizSeqNo)); + } + return jsonProperty; +} + +WEMQJSON *rmb_pub_encode_byte_body_for_wemq (unsigned int uiCmd, + StRmbMsg * ptSendMsg) +{ + if (ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptSendMsg is null"); + return NULL; + } + + WEMQJSON *jsonByteBody = json_object_new_object (); + json_object_object_add (jsonByteBody, + MSG_BODY_BYTE_BODY_APPHEADER_CONTENT_JSON, + json_object_new_string (ptSendMsg->cAppHeader)); + json_object_object_add (jsonByteBody, MSG_BODY_BYTE_BODY_APPHEADER_NAME_STR, + json_object_new_string (ptSendMsg->sysHeader. + cAppHeaderClass)); + json_object_object_add (jsonByteBody, MSG_BODY_BYTE_BODY_CONTENT_STR, + json_object_new_string_len (ptSendMsg->cContent, + ptSendMsg-> + iContentLen)); + json_object_object_add (jsonByteBody, MSG_BODY_BYTE_BODY_CREATETIME_LINT, + json_object_new_int64 (pRmbStConfig->ulNowTtime)); + json_object_object_add (jsonByteBody, MSG_BODY_COID_STR, + json_object_new_string ("#c")); + json_object_object_add (jsonByteBody, MSG_BODY_DELIVERYTIME_INT, + json_object_new_int (1)); + json_object_object_add (jsonByteBody, MSG_BODY_TTL_LINT, + json_object_new_int64 (ptSendMsg->ulMsgLiveTime)); + if (uiCmd == THREAD_MSG_CMD_SEND_REQUEST + || uiCmd == THREAD_MSG_CMD_SEND_REQUEST_ASYNC + || uiCmd == THREAD_MSG_CMD_SEND_REPLY) + { + json_object_object_add (jsonByteBody, MSG_BODY_SYN_BOOL, + json_object_new_boolean (1)); + } + else + { + json_object_object_add (jsonByteBody, MSG_BODY_SYN_BOOL, + json_object_new_boolean (0)); + } + + WEMQJSON *jsonSystemHeaderContent = + rmb_pub_encode_system_header_for_wemq (uiCmd, ptSendMsg); + if (jsonSystemHeaderContent == NULL) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_system_header return null"); + return NULL; + } + const char *systemHeaderContentStr = + json_object_get_string (jsonSystemHeaderContent); + json_object_object_add (jsonByteBody, + MSG_BODY_BYTE_BODY_SYSTEM_HEADER_CONTENT_JSON, + json_object_new_string (systemHeaderContentStr)); + + WEMQJSON *jsonBodyDest = rmb_pub_encode_body_dest_for_wemq (ptSendMsg); + if (jsonBodyDest == NULL) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_body_dest return null"); + return NULL; + } + const char *jsonBodyDestStr = json_object_get_string (jsonBodyDest); + json_object_object_add (jsonByteBody, MSG_BODY_DEST_JSON, + json_object_new_string (jsonBodyDestStr)); + + const char *byteBodyStr = json_object_get_string (jsonByteBody); + if (byteBodyStr == NULL) + { + json_object_put (jsonByteBody); + return NULL; + } + + int sysLen = strlen (byteBodyStr); + //LOGRMB(RMB_LOG_DEBUG, "Gen thread msg json byte body succ, len %d, %s\n", sysLen, byteBodyStr); + json_object_put (jsonSystemHeaderContent); + json_object_put (jsonBodyDest); + return jsonByteBody; +} + +//根据最新协议解析 +int rmb_pub_encode_body_for_wemq (unsigned int uiCmd, + StWemqThreadMsg * ptThreadMsg, + StRmbMsg * ptSendMsg, + unsigned long ulTimeToAlive) +{ + if (ptThreadMsg == NULL || ptSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptThreadMsg or ptSendMsg is null"); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonBody, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + if (THREAD_MSG_CMD_SEND_REQUEST_ASYNC == uiCmd) + { + snprintf (ptSendMsg->sysHeader.cExtFields, sizeof ("{\"rrType\": 1 }"), + "%s", "{\"rrType\": 1 }"); + } + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (uiCmd, ptSendMsg); + if (jsonBodyProperty == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + json_object_put (jsonBody); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_PROPERTY_JSON, jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (uiCmd, ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonBody, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + //json_object_object_add(jsonBody, MSG_BODY_BYTE_BODY_JSON, jsonByteBody); + + const char *bodyStr = json_object_get_string (jsonBody); + if (bodyStr == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + return -1; + } + ptThreadMsg->m_iBodyLen = strlen (bodyStr); + + //LOGRMB(RMB_LOG_DEBUG, "Get thread msg body succ, len=%d,%s", ptThreadMsg->m_iBodyLen, bodyStr); + ptThreadMsg->m_pBody = + (char *) malloc ((ptThreadMsg->m_iBodyLen + 1) * sizeof (char)); + if (ptThreadMsg->m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for ptThreadMsg->m_pBody failed"); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + return -1; + } +// strncpy(ptThreadMsg->m_pBody, bodyStr, ptThreadMsg->m_iBodyLen); + memcpy (ptThreadMsg->m_pBody, bodyStr, ptThreadMsg->m_iBodyLen); + ptThreadMsg->m_pBody[ptThreadMsg->m_iBodyLen] = '\0'; + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return 0; +} + +int rmb_pub_encode_thread_msg (unsigned int uiCmd, + StWemqThreadMsg * ptThreadMsg, + StRmbMsg * ptSendMsg, + unsigned long ulTimeToAlive) +{ + int iRet = -1; + + if (ptSendMsg == NULL || ptThreadMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "ptThreadMsg or ptSendMsg is null"); + return -1; + } + + iRet = rmb_pub_encode_header_for_wemq (uiCmd, ptThreadMsg, ptSendMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_header_for_wemq failed"); + return iRet; + } + + iRet = + rmb_pub_encode_body_for_wemq (uiCmd, ptThreadMsg, ptSendMsg, + ulTimeToAlive); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_body_for_wemq failed"); + return iRet; + } + LOGRMB (RMB_LOG_INFO, + "Get thread msg header succ, headerLen=%d,%s Get thread msg body succ, bodyLen=%d,%s\n", + ptThreadMsg->m_iHeaderLen, ptThreadMsg->m_pHeader, + ptThreadMsg->m_iBodyLen, ptThreadMsg->m_pBody); + + return 0; + +} + +char *rmb_printf_service_status (StRmbPub * pStPub, + StServiceStatus * pTmpService) +{ + //if ((int)pTmpService->cResult == 1) + if ((pTmpService->cResult & 0x0F) == 0x01) + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] null,gettime=%lu,InvalidTime=%lu pls check!", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pTmpService->ulGetTimes, pTmpService->ulInvalidTime); + } + //else if ((int)pTmpService->cResult == 2) + else if ((pTmpService->cResult & 0x0F) == 0x02) + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] route error,gettime=%lu,InvalidTime=%lu pls check!", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pTmpService->ulGetTimes, pTmpService->ulInvalidTime); + } + //else if ((int)pTmpService->cResult == 3) + else if ((pTmpService->cResult & 0x0F) == 0x03) + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] gsl_svr error,gettime=%lu,InvalidTime=%lu pls retry!", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pTmpService->ulGetTimes, pTmpService->ulInvalidTime); + } + else if ((int) pTmpService->cResult == 0) + { + if ((int) pTmpService->cRouteFlag == 2) + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] routeFlag=%d,dcn=%s,time=%lu,InvalidTime=%lu", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + (int) pTmpService->cRouteFlag, pTmpService->strTargetDcn, + pTmpService->ulGetTimes, pTmpService->ulInvalidTime); + } + else + { + snprintf (pStPub->printGslBuf, sizeof (pStPub->printGslBuf) - 1, + "service[%s,%s,%s,%d] routeFlag=%d,time=%lu,InvalidTime=%lu", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + (int) pTmpService->cRouteFlag, pTmpService->ulGetTimes, + pTmpService->ulInvalidTime); + } + + } + pStPub->printGslBuf[sizeof (pStPub->printGslBuf) - 1] = 0; + return pStPub->printGslBuf; +} + +/** + * 将字符串中的'/'替换为'-' + */ +static void rmb_change_slash_to_hyphen (char *str, int iLen) +{ + int i = 0; + for (i = 0; i < iLen && str[i] != '\0'; i++) + { + if (str[i] == '/') + { + str[i] = '-'; + } + } +} + +/** + * 用于判断消息发往wemq + */ +static int rmb_pub_send_mode (StRmbPub * pPub, StRmbMsg * pMsg) +{ + if (pPub == NULL || pMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pPub or pMsg is null"); + return -1; + } + + pMsg->iMsgMode = RMB_MSG_WEMQ; + + return 0; +} + +/** + * private func, request gsl for route and dcn + * 参见 + * api cache需求: + * 1. api使用同步的方式更新本地gsl cache,不做全量缓存 + * 2. api请求gsl服务的超时时间默认为1000ms + * 3. cache数据初始的超时时间为600s + * 4. cache数据更新逻辑如下: + * 1) cache中没有本次查询的数据, 则: + * result字段为0,则查询结果存入缓存,失效时间为600s + * result字段低4位为1,则查询结果存入缓存,失效时间为600s,向调用方返错 + * result字段低4位为2,则查询结果不存入缓存,向调用方返错 + * result字段低4位为3或者查询超时,查询结果不存入缓存,向调用方返错 + * 2) api发送消息时发现cache中数据已失效,则去gsl拉取数据: + * result字段为0,更新本地cache,同时将失效时间延后600s,使用最新查询到的数据发送rmb消息 + * result字段低4位为1,则查询结果存入缓存,失效时间为600s,向调用方返错 + * result字段低4位为2,则删除本地缓存数据,向调用方返错 + * result字段低4位为3或者查询超时,如果cache原数据的result字段为0,更新本地数据的失效时间,延后30s + */ +static int rmb_pub_send_gsl (StRmbPub * pStPub, StServiceStatus * pTmpService, + const char *cBizSeqNo, + const char *cConsumerSeqNo) +{ + //get dcn + //char pkgBuf[MAX_GSL_REQ_BUF_SIZE]; + char *p = pStPub->pkgBuf; + int iPkgLen = 0; + //*p = GSL_SUBCMD_QUERY_SERVICE; + *p = GSL_SUBCMD_NEW_QUERY_SERVICE; + p += 1; + iPkgLen += 1; + + int tmp = strlen (pTmpService->strTargetOrgId); + *p = tmp; + p += 1; + iPkgLen += 1; + memcpy (p, pTmpService->strTargetOrgId, tmp); + p += tmp; + iPkgLen += tmp; + + tmp = strlen (pRmbStConfig->cConsumerDcn); + *p = tmp; + p += 1; + iPkgLen += 1; + memcpy (p, pRmbStConfig->cConsumerDcn, tmp); + p += tmp; + iPkgLen += tmp; + + tmp = strlen (pTmpService->strServiceId); + *p = tmp; + p += 1; + iPkgLen += 1; + memcpy (p, pTmpService->strServiceId, tmp); + p += tmp; + iPkgLen += tmp; + + tmp = strlen (pTmpService->strScenarioId); + *p = tmp; + p += 1; + iPkgLen += 1; + memcpy (p, pTmpService->strScenarioId, tmp); + p += tmp; + iPkgLen += tmp; + + *p = pTmpService->cFlagForOrgId; + iPkgLen += 1; + + rmb_msg_set_bizSeqNo (pStPub->pSendMsg, cBizSeqNo); + rmb_msg_set_consumerSeqNo (pStPub->pSendMsg, cConsumerSeqNo); + rmb_msg_set_orgSysId (pStPub->pSendMsg, pRmbStConfig->cConsumerSysId); + rmb_msg_set_dest_v2_1 (pStPub->pSendMsg, GSL_DEFAULT_DCN, + GSL_DEFAULT_SERVICE_ID, GSL_DEFAULT_SCENE_ID, + GSL_DEFAULT_COMMON_ORGID); + + rmb_msg_set_content (pStPub->pSendMsg, pStPub->pkgBuf, iPkgLen); + char appHeader[5] = "{}"; + rmb_msg_set_app_header (pStPub->pSendMsg, appHeader, strlen (appHeader)); + + int iRet = + rmb_pub_send_and_receive (pStPub, pStPub->pSendMsg, pStPub->pRcvMsg, + pRmbStConfig->iQueryTimeout); + if (iRet == 0) + { + char receiveBuf[MAX_GSL_RSP_BUF_SIZE]; + unsigned int receiveLen = sizeof (receiveBuf); + rmb_msg_get_content (pStPub->pRcvMsg, receiveBuf, &receiveLen); + if (receiveLen == 0) + { + LOGRMB (RMB_LOG_ERROR, "GSL reply len=0, req=%s\n", + rmb_msg_print (pStPub->pSendMsg)); + rmb_errno = RMB_ERROR_GSL_SVR_ERROR; + return 3; + } + // result(char) + routeFlag(char) + targetDcn(cStr) + char result = *(receiveBuf + 1); + pTmpService->cResult = result; + + if (result == 0) + { + pTmpService->cRouteFlag = *(receiveBuf + 2); + if (pTmpService->cRouteFlag == 0 || pTmpService->cRouteFlag == 1) + { + LOGRMB (RMB_LOG_INFO, "GSL:[%s-%s-%s-%d] routeFlag=%d\n", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId, + (int) pTmpService->cRouteFlag); + return 0; + } + unsigned int uiDcnLen = *(receiveBuf + 3); + memcpy (pTmpService->strTargetDcn, receiveBuf + 4, uiDcnLen); + pTmpService->strTargetDcn[uiDcnLen] = 0; + + LOGRMB (RMB_LOG_INFO, + "GSL:[%s-%s-%s-%d],get succ!routeFlag=2,targetDcn=%s \n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pTmpService->strTargetDcn); + return 0; + } + //兼容老的gsl的错误返回码 + else if (result == 1) + { + LOGRMB (RMB_LOG_INFO, + "GSL:[%s-%s-%s-%d] service=NULL,result=1, uniqueID=%s\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId); + //pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } + else if (result == 2) + { + + LOGRMB (RMB_LOG_INFO, + "GSL:[%s-%s-%s-%d] service error,result=2, uniqueID=%s\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId); + //pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; + return 2; + } + else if (result == 3) + { + LOGRMB (RMB_LOG_INFO, + "GSL:[%s-%s-%s-%d] gsl svr error,result=3, uniqueID=%s\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId); + //pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + rmb_errno = RMB_ERROR_GSL_SVR_ERROR; + //return 3; + return 4; + } + ////////////////////////////// + else if ((result & 0x0F) == 0x01) + { + int index = (result & 0xF0) >> 4; + LOGRMB (RMB_LOG_INFO, "GSL:[%s-%s-%s-%d] uId=%s, result=0x%02x, %s\n", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId, + gsl_error[index].result, gsl_error[index].err_msg); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } + else if ((result & 0x0F) == 0x02) + { + int index = ((result & 0xF0) >> 4) + 16; + LOGRMB (RMB_LOG_INFO, "GSL:[%s-%s-%s-%d] uId=%s, result=0x%02x, %s\n", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId, + gsl_error[index].result, gsl_error[index].err_msg); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; + return 2; + } + else if ((result & 0x0F) == 0x03) + { + int index = ((result & 0xF0) >> 4) + 32; + LOGRMB (RMB_LOG_INFO, "GSL:[%s-%s-%s-%d] uId=%s, result=0x%02x, %s\n", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId, + pStPub->pRcvMsg->sysHeader.cUniqueId, + gsl_error[index].result, gsl_error[index].err_msg); + rmb_errno = RMB_ERROR_GSL_SVR_ERROR; + return 4; + } + } + else + { + if (rmb_errno == RMB_ERROR_SEND_RR_MSG_TIMEOUT) + { + LOGRMB (RMB_LOG_ERROR, + "GSL:[%s-%s-%s-%d],send and receive from GSL timeout.\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId); + pTmpService->cResult = 3; + return 4; + } + + LOGRMB (RMB_LOG_ERROR, + "GSL:[%s-%s-%s-%d],send and recevie from GSL error,iRet=%d!\n", + pTmpService->strServiceId, pTmpService->strScenarioId, + pTmpService->strTargetOrgId, (int) pTmpService->cFlagForOrgId, + iRet); + //pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + pTmpService->cResult = 3; + rmb_errno = RMB_ERROR_REQ_GSL_ERROR; + return 3; + } + return 0; +} + +/** + * 给gsl发染色消息 + */ + +int rmb_pub_send_dyed_msg_to_gsl (StRmbPub * pStPub) +{ + char cBizSeqNo[50] = ""; + char cConsumerSeqNo[50] = ""; + rmb_msg_random_uuid (cBizSeqNo, 32); + rmb_msg_random_uuid (cConsumerSeqNo, 32); + + rmb_msg_set_bizSeqNo (pStPub->pSendMsg, cBizSeqNo); + rmb_msg_set_consumerSeqNo (pStPub->pSendMsg, cConsumerSeqNo); + rmb_msg_set_orgSysId (pStPub->pSendMsg, pRmbStConfig->cConsumerSysId); + rmb_msg_set_dest_v2_1 (pStPub->pSendMsg, GSL_DEFAULT_DCN, + GSL_DEFAULT_SERVICE_ID, GSL_DEFAULT_SCENE_ID, + GSL_DEFAULT_COMMON_ORGID); + + rmb_msg_set_content (pStPub->pSendMsg, "", 0); + char appHeader[5] = "{}"; + rmb_msg_set_app_header (pStPub->pSendMsg, appHeader, strlen (appHeader)); + rmb_msg_set_dyedMsg (pStPub->pSendMsg, "true"); + + int iRet = + rmb_pub_send_and_receive (pStPub, pStPub->pSendMsg, pStPub->pRcvMsg, + pRmbStConfig->iQueryTimeout); + if (iRet == 1) + { + LOGRMB (RMB_LOG_DEBUG, "send dyed msg to GSL success,ret code is %d", + iRet); + } + rmb_msg_clear (pStPub->pSendMsg); + return iRet; +} + +//0:succ +//1:GSL服务id为空 +//2:GSL服务id路由错误 +//3:GSL服务器错误 +//-1:服务错误 + +int rmb_pub_send_gsl_and_insert_cache (StRmbPub * pStPub, StRmbMsg * pStMsg, + StServiceStatus * pTmpService, + StServiceStatus * hasCachedService) +{ + //pthread_mutex_lock(&pStPub->pubMutex); + if (hasCachedService != NULL) + { + //if (hasCachedService->ulGetTimes + pRmbStConfig->iCacheTimeoutTime * 1000 >= pRmbStConfig->ulNowTtime) + if (hasCachedService->ulInvalidTime >= pRmbStConfig->ulNowTtime) + { + //if (hasCachedService->cResult == 1) + if ((hasCachedService->cResult & 0x0F) == 0x01) + { + LOGRMB (RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service=NULL", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } +// else if (hasCachedService->cResult == 2) +// { +// LOGRMB(RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service error", +// pTmpService->strServiceId, +// pTmpService->strScenarioId, +// pTmpService->strTargetOrgId, +// (int)pTmpService->cFlagForOrgId +// ); +// rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; +// return 2; +// } + else if (hasCachedService->cResult == 0) + { + if (hasCachedService->cRouteFlag == 0 + || hasCachedService->cRouteFlag == 1) + { + return 0; + } + else + { + //LOGRMB(RMB_LOG_DEBUG, "nowTime=%lu,Cache:[%s]", pRmbStConfig->ulNowTtime, rmb_printf_service_status(pStPub, tmpService)); + if (strcmp (pStMsg->strTargetDcn, hasCachedService->strTargetDcn) != + 0) + { + LOGRMB (RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", + hasCachedService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, hasCachedService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + //LOGRMB(RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", hasCachedService->strTargetDcn, pStMsg->strTargetDcn); + } + return 0; + } + } + } + } + else + { + hasCachedService = + bsearch (pTmpService, pRmbStConfig->serviceStatusList, + pRmbStConfig->iCacheServiceNums, sizeof (StServiceStatus), + cmpServiceStatusStr); + if (hasCachedService != NULL) + { + //if (hasCachedService->ulGetTimes + pRmbStConfig->iCacheTimeoutTime * 1000 >= pRmbStConfig->ulNowTtime) + if (hasCachedService->ulInvalidTime >= pRmbStConfig->ulNowTtime) + { + //if (hasCachedService->cResult == 1) + if ((hasCachedService->cResult & 0x0F) == 0x01) + { + LOGRMB (RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service=NULL", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } +// else if (hasCachedService->cResult == 2) +// { +// LOGRMB(RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service error", +// pTmpService->strServiceId, +// pTmpService->strScenarioId, +// pTmpService->strTargetOrgId, +// (int)pTmpService->cFlagForOrgId +// ); +// rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; +// return 2; +// } + else if (hasCachedService->cResult == 0) + { + if (hasCachedService->cRouteFlag == 0 + || hasCachedService->cRouteFlag == 1) + { + return 0; + } + else + { + //LOGRMB(RMB_LOG_DEBUG, "nowTime=%lu,Cache:[%s]", pRmbStConfig->ulNowTtime, rmb_printf_service_status(pStPub, tmpService)); + if (strcmp (pStMsg->strTargetDcn, hasCachedService->strTargetDcn) + != 0) + { + LOGRMB (RMB_LOG_INFO, + "GSL DCN=%s is diffrent with input DCN=%s", + hasCachedService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, hasCachedService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + } + return 0; + } + } + } + } + } + int iRet = + rmb_pub_send_gsl (pStPub, pTmpService, pStMsg->sysHeader.cBizSeqNo, + pStMsg->sysHeader.cConsumerSeqNo); + if (iRet == 2 || iRet == 3) + { + pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + if (hasCachedService != NULL) + { + hasCachedService->cResult = pTmpService->cResult; + hasCachedService->cRouteFlag = pTmpService->cRouteFlag; + } + return iRet; + } +// if (iRet == 3) +// { +// pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; +// pTmpService->ulInvalidTime = pRmbStConfig->ulNowTtime + pRmbStConfig->iCacheFailedTimeoutTime * 1000; +// //pthread_mutex_unlock(&pStPub->pubMutex); +// return 3; +// } + + if (iRet == 4) + { + pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + pTmpService->ulInvalidTime = + pRmbStConfig->ulNowTtime + pRmbStConfig->iCacheFailedTimeoutTime * 1000; + if (hasCachedService != NULL) + { + if ((hasCachedService->cResult == 0) + || ((hasCachedService->cResult & 0x0F) == 0x01)) + { + hasCachedService->ulInvalidTime = + pRmbStConfig->ulNowTtime + + pRmbStConfig->iCacheFailedTimeoutTime * 1000; + } + } + return 4; + } + + //cache过期,且在本地存在 + if (hasCachedService != NULL) + { + pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + + hasCachedService->cResult = pTmpService->cResult; + hasCachedService->cRouteFlag = pTmpService->cRouteFlag; + hasCachedService->ulGetTimes = pRmbStConfig->ulNowTtime; + if (hasCachedService->cResult == 0) + { + memcpy (hasCachedService->strTargetDcn, pTmpService->strTargetDcn, + sizeof (hasCachedService->strTargetDcn)); + } + if (iRet == 0 || iRet == 1) + { + hasCachedService->ulInvalidTime = + pRmbStConfig->ulNowTtime + pRmbStConfig->iCacheSuccTimeoutTime * 1000; + } + else + { + hasCachedService->ulInvalidTime = + pRmbStConfig->ulNowTtime + + pRmbStConfig->iCacheFailedTimeoutTime * 1000; + } + } + else + { //本地无cach + //本地无cache,且返回结果为2或3,则不缓存 + if (iRet == 2 || iRet == 3 || iRet == 4) + return iRet; + + pTmpService->ulGetTimes = pRmbStConfig->ulNowTtime; + if (iRet == 0 || iRet == 1) + { + pTmpService->ulInvalidTime = + pRmbStConfig->ulNowTtime + pRmbStConfig->iCacheSuccTimeoutTime * 1000; + } + else + { + pTmpService->ulInvalidTime = + pRmbStConfig->ulNowTtime + + pRmbStConfig->iCacheFailedTimeoutTime * 1000; + } + //select + StServiceStatus *pTmp = NULL; + if (pRmbStConfig->iCacheServiceNums >= MAX_SERVICE_STATUS_CACHE_NUMS) + { + //find the oldest cache + int i = 0; + //unsigned long ulMinTimestamp = 1 << (sizeof(unsigned long)-1); + unsigned long ulMinTimestamp = + pRmbStConfig->serviceStatusList[0].ulGetTimes; + for (; i < MAX_SERVICE_STATUS_CACHE_NUMS; i++) + { + if (ulMinTimestamp > pRmbStConfig->serviceStatusList[i].ulGetTimes) + { + ulMinTimestamp = pRmbStConfig->serviceStatusList[i].ulGetTimes; + pTmp = &pRmbStConfig->serviceStatusList[i]; + } + } + pRmbStConfig->iCacheServiceNums -= 1; + } + else + { + pTmp = + &pRmbStConfig->serviceStatusList[pRmbStConfig->iCacheServiceNums]; + } + memcpy (pTmp, pTmpService, sizeof (StServiceStatus)); + pRmbStConfig->iCacheServiceNums += 1; + //sort + qsort (pRmbStConfig->serviceStatusList, pRmbStConfig->iCacheServiceNums, + sizeof (StServiceStatus), cmpServiceStatusStr); + } + int i = 0; + for (; i < pRmbStConfig->iCacheServiceNums; i++) + { + LOGRMB (RMB_LOG_INFO, "cache%dth:[%s]", i, + rmb_printf_service_status (pStPub, + &pRmbStConfig->serviceStatusList[i])); + } + //pthread_mutex_unlock(&pStPub->pubMutex); + //return pTmpService->cResult; + return iRet; +} + +/** + * before 0.9.15 version + * req: subcmd(char) + targetOrgId(cStr) + selfDcn(cStr) + serverId(cStr) + scenseId(cStr) + flag(char)(0: user 1: api) + * rsp: subcmd(char) + result(char) + routeFlag(char) + targetDcn(cStr) + * + * 0.9.15: + * req: subcmd -- 0x11 + * rsp: result -- 0x11 0x21 ... + * result 0x1x -- cache 600s + * result 0x2x -- clean cache + * return: + * 0:success + * 1:null + * 2:serverId error + * 3:GSL server error + */ +int rmb_pub_get_target_dcn (StRmbPub * pStPub, StRmbMsg * pStMsg) +{ + //search cache + //int iFLagForReqGsl = 1; + StServiceStatus tmpStatus; + tmpStatus.ulInvalidTime = 0; + StServiceStatus *pTmpService = &tmpStatus; + + pTmpService->cFlagForOrgId = pStMsg->iFLagForOrgId; + if (pStMsg->iFLagForOrgId == RMB_COMMIT_BY_OWN) + { + strncpy (pTmpService->strTargetOrgId, pStMsg->strTargetOrgId, + sizeof (pTmpService->strTargetOrgId) - 1); + } + else + { + strncpy (pTmpService->strTargetOrgId, pRmbStConfig->strOrgId, + sizeof (pTmpService->strTargetOrgId) - 1); + } + strncpy (pTmpService->strServiceId, pStMsg->strServiceId, + sizeof (pTmpService->strServiceId) - 1); + strncpy (pTmpService->strScenarioId, pStMsg->strScenarioId, + sizeof (pTmpService->strScenarioId) - 1); + + StServiceStatus *tmpService = + bsearch (pTmpService, pRmbStConfig->serviceStatusList, + pRmbStConfig->iCacheServiceNums, sizeof (StServiceStatus), + cmpServiceStatusStr); + if (tmpService != NULL) + { + //if (tmpService->ulGetTimes + pRmbStConfig->iCacheTimeoutTime * 1000 >= pRmbStConfig->ulNowTtime) + if (tmpService->ulInvalidTime >= pRmbStConfig->ulNowTtime) + { + //if (tmpService->cResult == 1) +// if (tmpService->cResult == 0x11 || tmpService->cResult == 0x21 || tmpService->cResult == 0x31 || +// tmpService->cResult == 0x41 || tmpService->cResult == 0x51 || tmpService->cResult == 0x61) + if ((tmpService->cResult & 0x0F) == 0x01) + { + LOGRMB (RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service=NULL", + pTmpService->strServiceId, + pTmpService->strScenarioId, + pTmpService->strTargetOrgId, + (int) pTmpService->cFlagForOrgId); + rmb_errno = RMB_ERROR_GSL_SERVICE_ID_NULL; + return 1; + } +// else if (tmpService->cResult == 2) +// { +// LOGRMB(RMB_LOG_ERROR, "Cache:[%s-%s-%s-%d] service error", +// pTmpService->strServiceId, +// pTmpService->strScenarioId, +// pTmpService->strTargetOrgId, +// (int)pTmpService->cFlagForOrgId +// ); +// rmb_errno = RMB_ERROR_GSL_SERVICE_ID_ERROR; +// return 2; +// } + else if (tmpService->cResult == 0) + { + if (tmpService->cRouteFlag == 0 || tmpService->cRouteFlag == 1) + { + return 0; + } + else + { + //LOGRMB(RMB_LOG_DEBUG, "nowTime=%lu,Cache:[%s]", pRmbStConfig->ulNowTtime, rmb_printf_service_status(pStPub, tmpService)); + if (strcmp (pStMsg->strTargetDcn, tmpService->strTargetDcn) != 0) + { + LOGRMB (RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", + tmpService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, tmpService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + //LOGRMB(RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", tmpService->strTargetDcn, pStMsg->strTargetDcn); + } + return 0; + } + } + } + else + { + LOGRMB (RMB_LOG_INFO, "cache time out!nowTime=%lu, Cache:[%s] ", + pRmbStConfig->ulNowTtime, rmb_printf_service_status (pStPub, + tmpService)); + } + } + pthread_mutex_lock (&pStPub->pubMutex); + int iRet = + rmb_pub_send_gsl_and_insert_cache (pStPub, pStMsg, pTmpService, + tmpService); + pthread_mutex_unlock (&pStPub->pubMutex); + if (iRet != 0) + { +// if (iRet == 3 && tmpService != NULL) + if (iRet == 4 && tmpService != NULL && tmpService->cResult == 0) + { + //copy dcn to msg + if (tmpService->cRouteFlag == 2) + { + if (strcmp (pStMsg->strTargetDcn, tmpService->strTargetDcn) != 0) + { + LOGRMB (RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", + tmpService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, tmpService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + //LOGRMB(RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", tmpService->strTargetDcn, pStMsg->strTargetDcn); + } + } + LOGRMB (RMB_LOG_ERROR, "ReqGsl error,but use cache! gsl=[%s],cache=%s", + rmb_printf_service_status (pStPub, pTmpService), + rmb_printf_service_status (pStPub, tmpService)); + return 0; + } + LOGRMB (RMB_LOG_ERROR, "ReqGsl gsl=[%s]", + rmb_printf_service_status (pStPub, pTmpService)); + return iRet; + } + else + { + //copy dcn to msg + // + if (pTmpService->cResult == 0 && pTmpService->cRouteFlag == 2) + { + if (strcmp (pStMsg->strTargetDcn, pTmpService->strTargetDcn) != 0) + { + LOGRMB (RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", + pTmpService->strTargetDcn, pStMsg->strTargetDcn); + strncpy (pStMsg->strTargetDcn, pTmpService->strTargetDcn, + sizeof (pStMsg->strTargetDcn) - 1); + //LOGRMB(RMB_LOG_INFO, "GSL DCN=%s is diffrent with input DCN=%s", pTmpService->strTargetDcn, pStMsg->strTargetDcn); + } + } + LOGRMB (RMB_LOG_INFO, "ReqGsl succ! gsl=[%s]", + rmb_printf_service_status (pStPub, pTmpService)); + } + return 0; +} + +int rmb_pub_set_destination_Interval (StRmbPub * pStPub, StRmbMsg * pStMsg) +{ + //req gsl control + if (pRmbStConfig->iReqGsl == 1) + { + if (!strcmp (pStMsg->strServiceId, GSL_DEFAULT_SERVICE_ID)) + { + strncpy (pStMsg->strTargetDcn, GSL_DEFAULT_DCN, + sizeof (pStMsg->strTargetDcn) - 1); + } + else + { + int iRet = rmb_pub_get_target_dcn (pStPub, pStMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_get_target_dcn error!iRet=%d", iRet); + return iRet; + } + } + } + + if (pStMsg->iEventOrService == RMB_EVENT_CALL) + { + snprintf (pStMsg->dest.cDestName, sizeof (pStMsg->dest.cDestName), + "%s/e/%s/%s/%c", pStMsg->strTargetDcn, pStMsg->strServiceId, + pStMsg->strScenarioId, *(pStMsg->strServiceId + 3)); + } + else + { + snprintf (pStMsg->dest.cDestName, sizeof (pStMsg->dest.cDestName), + "%s/s/%s/%s/%c", pStMsg->strTargetDcn, pStMsg->strServiceId, + pStMsg->strScenarioId, *(pStMsg->strServiceId + 3)); + } + pStMsg->dest.iDestType = RMB_DEST_TOPIC; + + //set pub message to wemq + rmb_pub_send_mode (pStPub, pStMsg); + + return 0; +} + +/** + * Function: rmb_pub_init + * Description: rmb pub initialize + * Return: + * 0: success + * -1: failed + */ +int rmb_pub_init (StRmbPub * pRmbPub) +{ + if (pRmbPub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub arg is null\n"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + + if (pRmbPub->uiContextNum == 1) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub has already init!"); + return 0; + } + pRmbPub->pContext = (StContext *) malloc (sizeof (StContext)); + if (pRmbPub->pContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub->pContext malloc error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + pRmbStConfig->uiPid = (unsigned int) getpid (); + memset (pRmbPub->pContext, 0, sizeof (StContext)); + pRmbPub->pContext->contextType = RMB_CONTEXT_TYPE_PUB; + + int iRet = rmb_context_init (pRmbPub->pContext); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_init failed!iRet=%d,error=%s", iRet, + get_rmb_last_error ()); + rmb_errno = RMB_ERROR_INIT_CONTEXT_FAIL; + return -3; + } + pRmbPub->uiContextNum = 1; + pRmbPub->pContext->pFather = (void *) pRmbPub; + + pRmbPub->ulLastTime = 0; + //rmb_pub_rand(pRmbPub); + + pRmbPub->pSendMsg = rmb_msg_malloc (); + if (pRmbPub->pSendMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_init malloc failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + + //pRmbPub->pRcvMsg = (StRmbMsg*)malloc(sizeof(StRmbMsg)); + pRmbPub->pRcvMsg = rmb_msg_malloc (); + if (pRmbPub->pRcvMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_init malloc failed!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + pthread_mutex_init (&pRmbPub->pubMutex, NULL); + rmb_pub_send_dyed_msg_to_gsl (pRmbPub); + + return 0; +} + +/** + * Function: rmb_pub_init_python + * Description: rmb pub initialize + * Return: + * 0: success + * -1: failed + */ +int rmb_pub_init_python () +{ + pRmbGlobalPub = (StRmbPub *) calloc (1, sizeof (StRmbPub)); + if (pRmbGlobalPub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbGlobalPub arg is null\n"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + + rmb_pub_init (pRmbGlobalPub); + + return 0; +} + +int rmb_pub_send_msg_to_wemq (StRmbPub * pRmbPub, StRmbMsg * pMsg) +{ + if (pRmbPub == NULL || pMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub or pMsg is null"); + return -1; + } + + //check dest is set + if (rmb_check_msg_valid (pMsg) != 0) + { + rmb_errno = RMB_ERROR_MSG_MISSING_PART; + return -2; + } + + if (pMsg->iEventOrService == (int) RMB_SERVICE_CALL) + { + LOGRMB (RMB_LOG_ERROR, + "rmb pub event interface can't send rr msg,serviceId=%s!\n", + pMsg->strServiceId); + rmb_errno = RMB_ERROR_EVENT_INTERFACE_CAN_NOT_SEND_RR_MSG; + return -3; + } + + int iRet = 0; + + iRet = rmb_msg_init (pMsg, pRmbStConfig, C_TYPE_WEMQ); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_msg_init failed!iRet=%d\n", iRet); + return -5; + } + + if (pMsg->ulMsgLiveTime == 0 + || pMsg->ulMsgLiveTime > DEFAULT_MSG_MAX_LIVE_TIME) + { + pMsg->ulMsgLiveTime = DEFAULT_MSG_MAX_LIVE_TIME; + } + + pMsg->cLogicType = EVENT_PKG_IN_WEMQ; + GetRmbNowLongTime (); + pMsg->sysHeader.ulSendTime = pRmbStConfig->ulNowTtime; + + StContext *pStContext = pRmbPub->pContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + + if (pMsg->ulMsgLiveTime == 0 + || pMsg->ulMsgLiveTime > DEFAULT_MSG_MAX_LIVE_TIME) + { + pMsg->ulMsgLiveTime = DEFAULT_MSG_MAX_LIVE_TIME; + } + + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_MSG; + iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pMsg, + pMsg->ulMsgLiveTime); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!"); + rmb_send_log_for_error (pStContext->pContextProxy, RMB_ERROR_ENCODE_FAIL, + "wemq_pub_encode_thread_msg error", pMsg); + return iRet; + } + + pthread_mutex_lock (&pContextProxy->eventMutex); + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!,iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "wemq_kfifo_put error", pMsg); + return -5; + } + + struct timeval tv; + gettimeofday (&tv, NULL); + struct timespec ts_timeout; + ts_timeout.tv_sec = + tv.tv_sec + (tv.tv_usec / 1000 + pRmbStConfig->accessAckTimeOut) / 1000; + ts_timeout.tv_nsec = + ((tv.tv_usec / 1000 + + pRmbStConfig->accessAckTimeOut) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForEvent = -1; + if (pContextProxy->iFlagForEvent == -1) + { + //reset seq + pContextProxy->iSeqForEvent = g_iSendReqForEvent; + LOGRMB (RMB_LOG_DEBUG, "reset seq:%ld, pContextProxy->iSeqForEvent:%ld", + g_iSendReqForEvent, pContextProxy->iSeqForEvent); + + pthread_cond_timedwait (&pContextProxy->eventCond, + &pContextProxy->eventMutex, &ts_timeout); + + } + pthread_mutex_unlock (&pContextProxy->eventMutex); + + switch (pContextProxy->iFlagForEvent) + { + case RMB_CODE_TIME_OUT: + LOGRMB (RMB_LOG_ERROR, "time out!req=%s", rmb_msg_print (pMsg)); + rmb_errno = RMB_ERROR_SEND_EVENT_MSG_FAIL; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_SEND_EVENT_MSG_FAIL, + "wemq send event msg ack timeout", pMsg); + return -6; + case RMB_CODE_SUSS: + LOGRMB (RMB_LOG_DEBUG, "send msg succ!req=%s\n", rmb_msg_print (pMsg)); + return 0; + case RMB_CODE_OTHER_FAIL: + LOGRMB (RMB_LOG_ERROR, "send msg failed!req=%s", rmb_msg_print (pMsg)); + return -6; + case RMB_CODE_AUT_FAIL: + LOGRMB (RMB_LOG_ERROR, "Authentication failed!req=%s", + rmb_msg_print (pMsg)); + return -5; + } + +} + +static int rmb_pub_send_and_receive_to_wemq (StRmbPub * pRmbPub, + StRmbMsg * pSendMsg, + StRmbMsg * pRevMsg, + unsigned int uiTimeOut) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pSendMsg, "pSendMsg"); + RMB_CHECK_POINT_NULL (pRevMsg, "pRevMsg"); + + if (pSendMsg->iEventOrService == (int) RMB_EVENT_CALL) + { + LOGRMB (RMB_LOG_ERROR, "rr interface can't send event msg!"); + rmb_errno = RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG; + return -1; + } + + int iRet = 0; + + iRet = rmb_msg_init (pSendMsg, pRmbStConfig, C_TYPE_WEMQ); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_msg_init failed!iRet=%d", iRet); + return -3; + } + + if (pSendMsg->ulMsgLiveTime == 0 + || pSendMsg->ulMsgLiveTime > DEFAULT_MSG_MAX_LIVE_TIME) + { + pSendMsg->ulMsgLiveTime = uiTimeOut; + } + + pSendMsg->cLogicType = REQ_PKG_IN_WEMQ; + GetRmbNowLongTime (); + pSendMsg->sysHeader.ulSendTime = pRmbStConfig->ulNowTtime; + + StContext *pStContext = pRmbPub->pContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_REQUEST; + iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pSendMsg, + uiTimeOut); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!"); + rmb_send_log_for_error (pStContext->pContextProxy, RMB_ERROR_ENCODE_FAIL, + "wemq_pub_encode_thread_msg error", pSendMsg); + return -4; + } + + pthread_mutex_lock (&pContextProxy->rrMutex); + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "wemq_kfifo_put error", pSendMsg); + return -5; + } + + struct timeval tv; + gettimeofday (&tv, NULL); + struct timespec ts_timeout; + ts_timeout.tv_sec = tv.tv_sec + (tv.tv_usec / 1000 + uiTimeOut) / 1000; + ts_timeout.tv_nsec = ((tv.tv_usec / 1000 + uiTimeOut) % 1000) * 1000 * 1000; + + int i = 0; + unsigned int uiUniqueLen = strlen (pSendMsg->sysHeader.cUniqueId); + pContextProxy->iFlagForRR = -1; + + if (pContextProxy->iFlagForRR == -1) + { + //add uniqueId + strncpy (pContextProxy->stUnique.unique_id, pSendMsg->sysHeader.cUniqueId, + uiUniqueLen); + pContextProxy->stUnique.unique_id[uiUniqueLen] = '\0'; + pContextProxy->stUnique.flag = 1; + + } + + pthread_cond_timedwait (&pContextProxy->rrCond, &pContextProxy->rrMutex, + &ts_timeout); + + if (pContextProxy->iFlagForRR == RMB_CODE_TIME_OUT) + { + pContextProxy->stUnique.flag = 0; + + } + pthread_mutex_unlock (&pContextProxy->rrMutex); + + switch (pContextProxy->iFlagForRR) + { + case RMB_CODE_TIME_OUT: + LOGRMB (RMB_LOG_ERROR, "time out!req=%s", rmb_msg_print (pSendMsg)); + rmb_errno = RMB_ERROR_SEND_RR_MSG_TIMEOUT; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_SEND_RR_MSG_TIMEOUT, + "wemq send rr msg timeout", pSendMsg); + return -6; + case RMB_CODE_SUSS: + trans_json_2_rmb_msg (pRevMsg, pContextProxy->mPubRRBuf, + RESPONSE_TO_CLIENT); + LOGRMB (RMB_LOG_DEBUG, "receive reply succ,buf:%s", + pContextProxy->mPubRRBuf); + pRevMsg->cPkgType = RR_TOPIC_PKG; + return 0; + case RMB_CODE_OTHER_FAIL: + LOGRMB (RMB_LOG_ERROR, "receive reply failed!req=%s", + rmb_msg_print (pSendMsg)); + rmb_errno = RMB_ERROR_SEND_RR_MSG_TIMEOUT; + return -4; + case RMB_CODE_AUT_FAIL: + LOGRMB (RMB_LOG_ERROR, "receive reply Authentication failed!req=%s", + rmb_msg_print (pSendMsg)); + rmb_errno = RMB_ERROR_SEND_RR_MSG_TIMEOUT; + return -5; + case RMB_CODE_DYED_MSG: + LOGRMB (RMB_LOG_INFO, "receive dyed msg:%s", pContextProxy->mPubRRBuf); + return 1; + } + +} + +int rmb_pub_send_rr_msg_async_to_wemq (StRmbPub * pRmbPub, + StRmbMsg * pSendMsg, + unsigned int uiTimeOut) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pSendMsg, "pSendMsg"); + + if (pSendMsg->iEventOrService == (int) RMB_EVENT_CALL) + { + LOGRMB (RMB_LOG_ERROR, "async rr interface can't send event msg!"); + rmb_errno = RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG; + return -1; + } + + //pub connect status error + //if (pRmbPub->pContext->pContextProxy->iFlagForPublish == 0) { + // LOGRMB(RMB_LOG_ERROR, "rmb pub not connect to access!!!"); + // return -4; + //} + + int iRet = 0; +// iRet = rmb_pub_set_destination_Interval(pRmbPub, pSendMsg); +// if (iRet != 0) { +// LOGRMB(RMB_LOG_ERROR, "rmb set destination error!serviceId=%s,sceneId=%s,iRet=%d", pSendMsg->strServiceId, pSendMsg->strScenarioId, iRet); +// return -2; +// } + LOGRMB (RMB_LOG_DEBUG, "pubMsg dest=%d,%s,replyTo=%s", + pSendMsg->dest.iDestType, pSendMsg->dest.cDestName, + pSendMsg->replyTo.cDestName); + + iRet = rmb_msg_init (pSendMsg, pRmbStConfig, C_TYPE_WEMQ); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_msg_init failed!iRet=%d", iRet); + return -3; + } + + if (uiTimeOut > RR_ASYNC_MSG_MAX_LIVE_TIME) + { + LOGRMB (RMB_LOG_ERROR, "RR sync ttl too large, max value is:%ld", + RR_ASYNC_MSG_MAX_LIVE_TIME); + return -4; + } + + if (pSendMsg->ulMsgLiveTime == 0 + || pSendMsg->ulMsgLiveTime > DEFAULT_MSG_MAX_LIVE_TIME) + { + pSendMsg->ulMsgLiveTime = uiTimeOut; + } + + GetRmbNowLongTime (); + pSendMsg->sysHeader.ulSendTime = pRmbStConfig->ulNowTtime; + pSendMsg->replyTo.iDestType = RMB_DEST_TOPIC; + + StContext *pStContext = pRmbPub->pContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_REQUEST_ASYNC; + iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pSendMsg, 0); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!"); + rmb_send_log_for_error (pStContext->pContextProxy, RMB_ERROR_ENCODE_FAIL, + "wemq_pub_encode_thread_msg error", pSendMsg); + return iRet; + } + unsigned int uiUniqueLen = strlen (pSendMsg->sysHeader.cUniqueId); + int i = 0; + struct timeval tv_now; + gettimeofday (&tv_now, NULL); + unsigned long ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + int iFlagForList = 0; + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncNew. + get_array_size (&pContextProxy->pUniqueListForRRAsyncNew); i++) + { + + if (pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag == 0) + { + pthread_mutex_lock (&pContextProxy->rrMutex); + snprintf (pContextProxy->pUniqueListForRRAsyncNew.Data[i].unique_id, + sizeof (pContextProxy->pUniqueListForRRAsyncNew.Data[i]. + unique_id), "%s", pSendMsg->sysHeader.cUniqueId); + snprintf (pContextProxy->pUniqueListForRRAsyncNew.Data[i].biz_seq, + sizeof (pContextProxy->pUniqueListForRRAsyncNew.Data[i]. + biz_seq), "%s", pSendMsg->sysHeader.cBizSeqNo); + pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag = 1; + pContextProxy->pUniqueListForRRAsyncNew.Data[i].timeStamp = ulNowTime; + pContextProxy->pUniqueListForRRAsyncNew.Data[i].timeout = uiTimeOut; + iFlagForList = 1; + pthread_mutex_unlock (&pContextProxy->rrMutex); + break; + } + } + //已有空间已装满 + if (iFlagForList == 0) + { + LOGRMB (RMB_LOG_INFO, "local list for rr async push back"); + StUniqueIdList uniqueIdList; + strncpy (uniqueIdList.unique_id, pSendMsg->sysHeader.cUniqueId, + uiUniqueLen); + uniqueIdList.unique_id[uiUniqueLen] = '\0'; + uniqueIdList.flag = 1; + uniqueIdList.timeStamp = ulNowTime; + uniqueIdList.timeout = uiTimeOut; + pthread_mutex_lock (&pContextProxy->rrMutex); + pContextProxy->pUniqueListForRRAsyncNew.Input (uniqueIdList, + &pContextProxy-> + pUniqueListForRRAsyncNew); + pthread_mutex_unlock (&pContextProxy->rrMutex); + } + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "wemq_kfifo_put error", pSendMsg); + return -4; + } + + pContextProxy->iFlagForRRAsync = 1; + return 0; +} + +/** +Function: wemq_pub_reply_msg +Description:send report packet +Retrun: + 0 --success + -1 --failed +*/ +int rmb_pub_reply_msg_for_wemq (StRmbPub * pRmbPub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + if (pRmbPub == NULL || pStReceiveMsg == NULL || pStReplyMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub or pStReceiveMsg or pStReplyMsg is null"); + return -1; + } + + if (strlen (pStReceiveMsg->replyTo.cDestName) == 0) + { + LOGRMB (RMB_LOG_ERROR, "receiveMsg has no replyTo,can't reply!\n"); + return -2; + } + + //pub connect status error + //if (pRmbPub->pContext->pContextProxy->iFlagForPublish == 0) { + // LOGRMB(RMB_LOG_ERROR, "rmb pub not connect to access!!!"); + // return -4; + //} + + memcpy (&pStReplyMsg->sysHeader, &pStReceiveMsg->sysHeader, + sizeof (pStReceiveMsg->sysHeader)); + memcpy (&pStReplyMsg->dest, &pStReceiveMsg->replyTo, + sizeof (pStReceiveMsg->replyTo)); + + //serviceId + memcpy (pStReplyMsg->strServiceId, pStReceiveMsg->strServiceId, + sizeof (pStReceiveMsg->strServiceId)); + //scenarioId + memcpy (pStReplyMsg->strScenarioId, pStReceiveMsg->strScenarioId, + sizeof (pStReceiveMsg->strScenarioId)); + //dcn + memcpy (pStReplyMsg->strTargetDcn, pStReceiveMsg->strTargetDcn, + sizeof (pStReceiveMsg->strTargetDcn)); + //organization + memcpy (pStReplyMsg->strTargetOrgId, pStReceiveMsg->strTargetOrgId, + sizeof (pStReceiveMsg->strTargetOrgId)); + //ttl + pStReplyMsg->ulMsgLiveTime = pStReceiveMsg->ulMsgLiveTime; + + strncpy (pStReplyMsg->cCorrId, pStReceiveMsg->cCorrId, + sizeof (pStReceiveMsg->cCorrId)); + pStReplyMsg->iCorrLen = pStReceiveMsg->iCorrLen; + pStReplyMsg->cApiType = C_TYPE_WEMQ; + pStReplyMsg->cLogicType = RSP_PKG_OUT_WEMQ; + + GetRmbNowLongTime (); + pStReplyMsg->sysHeader.ulReplyTime = pRmbStConfig->ulNowTtime; +/* + while (CURRENT_WINDOW_SIZE >= DEFAULT_WINDOW_SIZE) { + LOGRMB(RMB_LOG_ERROR, "Send Window Full, recvSeq=%u,sendSeq=%u", g_uiRecvMsgSeq, g_uiSendMsgSeq); + usleep(1000); + } +*/ + StContext *pStContext = pRmbPub->pContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_REPLY; + int iRet = 0; + iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pStReplyMsg, + 0); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_thread_msg error!"); + rmb_send_log_for_error (pStContext->pContextProxy, RMB_ERROR_ENCODE_FAIL, + "wemq_reply_encode_thread_msg error", + pStReplyMsg); + return iRet; + } + + iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "reply message wemq_kfifo_put error", + pStReplyMsg); + return rmb_errno; + } + + return 0; +} + +/** + * Function: rmb_pub_send_msg + * Description: send event msg + * Return: + * 0: success + * -1: failed + * -2: queue full + */ +int rmb_pub_send_msg (StRmbPub * pRmbPub, StRmbMsg * pStMsg) +{ + + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pStMsg, "pStMsg"); + + if (rmb_check_msg_valid (pStMsg) != 0) + { + rmb_errno = RMB_ERROR_MSG_MISSING_PART; + return rmb_errno; + } + + if (pStMsg->iEventOrService == (int) RMB_SERVICE_CALL) + { + LOGRMB (RMB_LOG_ERROR, "event interface can't send rr msg,serviceId=%s!", + pStMsg->strServiceId); + rmb_errno = RMB_ERROR_EVENT_INTERFACE_CAN_NOT_SEND_RR_MSG; + return rmb_errno; + } + + int iRet = rmb_pub_set_destination_Interval (pRmbPub, pStMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb set destination error!serviceId=%s,sceneId=%s,iRet=%d,error=%s", + pStMsg->strServiceId, pStMsg->strScenarioId, iRet, + get_rmb_last_error ()); + return rmb_errno; + } + + return rmb_pub_send_msg_to_wemq (pRmbPub, pStMsg); + +} + +/** + * Function: rmb_pub_send_msg_python + * Description: send event msg_python + * Return: + * 0: success + * -1: failed + * -2: queue full + */ +int rmb_pub_send_msg_python (StRmbMsg * pStMsg) +{ + StRmbPub *pRmbPub = pRmbGlobalPub; + + return rmb_pub_send_msg (pRmbPub, pStMsg); + +} + +/** +Function: rmb_pub_send_rr_msg +Description:send RR asynchronous message +Retrun: + 0 --success + -1 --failed + -2 --queue full +*/ +int rmb_pub_send_rr_msg_async (StRmbPub * pRmbPub, StRmbMsg * pStMsg, + unsigned int uiTimeOut) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pStMsg, "pStMsg"); + + if (pStMsg->iEventOrService == (int) RMB_EVENT_CALL) + { + LOGRMB (RMB_LOG_ERROR, "aync RR interface can't send event msg!"); + rmb_errno = RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG; + return rmb_errno; + } + + //set destination + int iRet = rmb_pub_set_destination_Interval (pRmbPub, pStMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb set destination error!serviceId=%s,sceneId=%s,iRet=%d", + pStMsg->strServiceId, pStMsg->strScenarioId, iRet); + return rmb_errno; + } + + return rmb_pub_send_rr_msg_async_to_wemq (pRmbPub, pStMsg, uiTimeOut); + +} + +/** +Function: rmb_pub_send_rr_msg_async_python +Description:send RR asynchronous message +Retrun: + 0 --success + -1 --failed + -2 --queue full +*/ +int rmb_pub_send_rr_msg_async_python (StRmbMsg * pStMsg, + unsigned int uiTimeOut) +{ + StRmbPub *pRmbPub = pRmbGlobalPub; + + return rmb_pub_send_rr_msg_async (pRmbPub, pStMsg, uiTimeOut); +} + +/** +Function: rmb_pub_send_and_receive +Description:send message and wait for report +Retrun: + 0 --success + -1 --timeout + -2 --error +*/ +int rmb_pub_send_and_receive (StRmbPub * pRmbPub, StRmbMsg * pSendMsg, + StRmbMsg * pRevMsg, unsigned int uiTimeOut) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pSendMsg, "pSendMsg"); + RMB_CHECK_POINT_NULL (pRevMsg, "pRevMsg"); + + if (pSendMsg->iEventOrService == (int) RMB_EVENT_CALL) + { + LOGRMB (RMB_LOG_ERROR, "RR interface can't send event msg!"); + rmb_errno = RMB_ERROR_RR_INTERFACE_CAN_NOT_SEND_EVENT_MSG; + return rmb_errno; + } + + //set destination + int iRet = rmb_pub_set_destination_Interval (pRmbPub, pSendMsg); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "rmb set destination error!serviceId=%s,sceneId=%s,iRet=%d", + pSendMsg->strServiceId, pSendMsg->strScenarioId, iRet); + return rmb_errno; + } + + return rmb_pub_send_and_receive_to_wemq (pRmbPub, pSendMsg, pRevMsg, + uiTimeOut); + +} + +int rmb_pub_send_and_receive_python (StRmbMsg * pSendMsg, StRmbMsg * pRevMsg, + unsigned int uiTimeOut) +{ + StRmbPub *pRmbPub = pRmbGlobalPub; + + return rmb_pub_send_and_receive (pRmbPub, pSendMsg, pRevMsg, uiTimeOut); +} + +/** +Function: rmb_pub_reply_msg +Description:send report packet +Retrun: + 0 --success + -1 --failed +*/ +int rmb_pub_reply_msg (StRmbPub * pRmbPub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + RMB_CHECK_POINT_NULL (pStReceiveMsg, "pStReceiveMsg"); + RMB_CHECK_POINT_NULL (pStReplyMsg, "pStReplyMsg"); + if (strlen (pStReceiveMsg->replyTo.cDestName) == 0) + { + //LOGRMB(RMB_LOG_INFO, "rmb receivemsg reply destname empty"); + LOGRMB (RMB_LOG_WARN, "pStReceiveMsg->replyTo.cDestName=%s", + pStReceiveMsg->replyTo.cDestName); + return 0; + } + return rmb_pub_reply_msg_for_wemq (pRmbPub, pStReceiveMsg, pStReplyMsg); + +} + +/** +Function: rmb_pub_close +Description:close pub +Retrun: + 0 --success + -1 --failed +*/ +int rmb_pub_close (StRmbPub * pRmbPub) +{ + if (pRmbPub == NULL || pRmbPub->pContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub or pRmbPub->pContext is null"); + return 0; + } + + //wemq + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pRmbPub->pContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pRmbPub->pContext->pContextProxy; + + //pContextProxy->iFlagForRun = 0; + if (rmb_pub_send_client_goodbye_to_wemq (pRmbPub) != 0) + { + LOGRMB (RMB_LOG_DEBUG, "rmb_pub_send_client_goodbye_to_wemq failed"); + } + pContextProxy->iFlagForRun = 0; + GetRmbNowLongTime (); + pContextProxy->ulGoodByeTime = pRmbStConfig->ulNowTtime; + LOGRMB (RMB_LOG_DEBUG, "pthread_join mainThreadId"); + if (pContextProxy->mainThreadId != 0) + { + pthread_join (pContextProxy->mainThreadId, NULL); + } + + LOGRMB (RMB_LOG_DEBUG, "pthread_join coThreadId"); + if (pContextProxy->coThreadId != 0) + { + pthread_join (pContextProxy->coThreadId, NULL); + } + } + } + return 0; +} + +int rmb_pub_close_python () +{ + StRmbPub *pRmbPub = pRmbGlobalPub; + + int ret = rmb_pub_close_v2 (pRmbPub); + free (pRmbPub); + return ret; +} + +/** +Function: rmb_pub_close_v2 +Description:close pub +Retrun: + 0 --success + -1 --failed +*/ +int rmb_pub_close_v2 (StRmbPub * pRmbPub) +{ + if (pRmbPub == NULL || pRmbPub->pContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbPub or pRmbPub->pContext is null"); + return 0; + } + + //wemq + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pRmbPub->pContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pRmbPub->pContext->pContextProxy; + + pContextProxy->iFlagForRun = 0; + GetRmbNowLongTime (); + pContextProxy->ulGoodByeTime = pRmbStConfig->ulNowTtime; + LOGRMB (RMB_LOG_DEBUG, "pthread_join mainThreadId"); + if (pContextProxy->mainThreadId != 0) + { + pthread_join (pContextProxy->mainThreadId, NULL); + } + + LOGRMB (RMB_LOG_DEBUG, "pthread_join coThreadId"); + if (pContextProxy->coThreadId != 0) + { + pthread_join (pContextProxy->coThreadId, NULL); + } + } + } + + return 0; +} + +int rmb_pub_send_client_goodbye_to_wemq (StRmbPub * pRmbPub) +{ + RMB_CHECK_POINT_NULL (pRmbPub, "pRmbPub"); + + stContextProxy *pContextProxy = pRmbPub->pContext->pContextProxy; + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_CLIENT_GOODBYE; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return -2; + } + //add type + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (CLIENT_GOODBYE_REQUEST)); + //add seq + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + //add status + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "header is null"); + json_object_put (jsonHeader); + return -2; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%u, %s", + stThreadMsg.m_iHeaderLen, header_str) stThreadMsg.m_pHeader = + (char *) malloc ((stThreadMsg.m_iHeaderLen + 1) * sizeof (char)); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for stThreadMsg.m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + stThreadMsg.m_iBodyLen = 0; + stThreadMsg.m_pBody = NULL; + + int iRet = wemq_kfifo_put (&pContextProxy->pubFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error,iRet=%d!\n", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return rmb_errno; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->goodByeTimeOut) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->goodByeTimeOut) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForGoodBye = 0; + pthread_mutex_lock (&pContextProxy->goodByeMutex); + if (pContextProxy->iFlagForGoodBye == 0) + { + pthread_cond_timedwait (&pContextProxy->goodByeCond, + &pContextProxy->goodByeMutex, &timeout); + } + pthread_mutex_unlock (&pContextProxy->goodByeMutex); + + if (pContextProxy->iFlagForGoodBye != 1) + { + LOGRMB (RMB_LOG_ERROR, "send pub client goodBye timeout!"); + rmb_errno = RMB_ERROR_CLIENT_GOODBYE_TIMEOUT; + return rmb_errno; + } + + LOGRMB (RMB_LOG_DEBUG, "send and recv sub client goodbye succ"); + + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_sub.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_sub.c new file mode 100644 index 0000000000..7ca7ea4b73 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_sub.c @@ -0,0 +1,1379 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "rmb_common.h" +#include "rmb_errno.h" +#include "rmb_sub.h" +#include "rmb_udp.h" +#include "rmb_pub.h" +#include "rmb_list.h" +#include "rmb_context.h" +#include "wemq_thread.h" + +#define SRV_GOV_DATA_LVQ "SRV_GOV_DATA_LVQ" +#define SRV_BROADCAST_LVQ "BROADCAST_DATA_LVQ" + +#define atomic_set(x, y) __sync_lock_test_and_set((x), (y)) + +static StRmbPub *pRmbGlobalSub; + +//****************************************private************************************************ + +//根据类型获取mq +StMqInfo *rmb_sub_get_mq_by_type (StRmbSub * stRmbSub, int iType); + +void rmb_get_topic_group (void *args); + +int rmb_sub_add_rr_topic_v2 (StRmbSub * pStRmbSub); +int rmb_sub_add_listen_to_wemq (StRmbSub * pRmbSub, + const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize, const char *cDcn, + const char *cSysId); +int wemq_sub_reply_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg); +int wemq_sub_ack_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg); + +//int wemq_sub_add_listen_topic_bypass(StRmbSub *pStRmbSub, const char *cTopic); +int wemq_sub_add_listen_topic_bypass (StRmbSub * pStRmbSub, + const char **cTopic, + unsigned int uiTopicSize); + +int wemq_sub_add_start_to_access (StRmbSub * pStRmbSub); + +//************************************************************************************************* + +static unsigned long ulGetTopicGroupPthreadId = 0; + +static StRmbTopicInfo rmbTopicInfo[1024]; +static volatile int rmbTopicIndex = -1; + +unsigned long rmb_get_topic_thread_id () +{ + return ulGetTopicGroupPthreadId; +} + +/** + * Function: rmb_sub_init + * Description: rmb sub initialize + * Return: + * 0: success + * other: failed + */ +int rmb_sub_init (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub is null"); + return -1; + } + + if (pStRmbSub->uiContextNum == 1) + { + LOGRMB (RMB_LOG_ERROR, + " sub had inited. uiContextNum is :%u, max context is : %u", + pStRmbSub->uiContextNum, 1); + return 0; + } + + pStRmbSub->pStContext = (StContext *) malloc (sizeof (StContext)); + if (pStRmbSub->pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub->pContext malloc error!"); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -1; + } + pRmbStConfig->uiPid = (unsigned int) getpid (); + memset (pStRmbSub->pStContext, 0, sizeof (StContext)); + + pStRmbSub->pQueueInfo = + (st_rmb_queue_info *) malloc (sizeof (st_rmb_queue_info) * + MAX_LISTEN_TOPIC_NUM); + if (pStRmbSub->pQueueInfo == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub->pQueueInfo malloc error!"); + return -1; + } + memset (pStRmbSub->pQueueInfo, 0x00, + (sizeof (st_rmb_queue_info) * MAX_LISTEN_TOPIC_NUM)); + pStRmbSub->iQueueNum = 0; + + //pStRmbSub->uiFlagForFilter = RMB_FILTER_FLAG_FOR_RR_ASYNC; + + pStRmbSub->pStContext->contextType = RMB_CONTEXT_TYPE_SUB; + + //init context + int iRet = rmb_context_init (pStRmbSub->pStContext); + if (iRet < 0) + { + rmb_errno = RMB_ERROR_INIT_CONTEXT_FAIL; + return -2; + } + + //init notify, from init_context to here, 1.8.0 + iRet = rmb_notify_init (&(pStRmbSub->pStContext->fifoMq)); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "rmb_notify_init error!iRet=%u", iRet); + return -3; + } + + pStRmbSub->pStContext->pFather = (void *) pStRmbSub; + + pStRmbSub->uiContextNum = 1; + + return 0; +} + +/** + * Function: rmb_sub_init_python + * Description: rmb sub initialize + * Return: + * 0: success + * -1: failed + */ +int rmb_sub_init_python () +{ + + pRmbGlobalSub = (StRmbSub *) calloc (1, sizeof (StRmbSub)); + if (pRmbGlobalSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pRmbGlobalSub arg is null\n"); + rmb_errno = RMB_ERROR_ARGV_NULL; + return -1; + } + rmb_sub_init (pRmbGlobalSub); +} + +/** + * Function: rmb_sub_add_reveive_rsp + * Description: init, sub add receive RR async report packages + * Return: + * 0: success + * other: failed + */ +int rmb_sub_add_reveive_rsp (StRmbSub * pStRmbSub, unsigned short usRspPort) +{ + int iRet = 0; + + iRet = + rmb_context_add_rsp_socket (pStRmbSub->pStContext, pRmbStConfig->cHostIp, + usRspPort); + if (iRet != 0) + { + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return rmb_errno; + } + return 0; +} + +int rmb_sub_add_reveive_rsp_by_mq (StRmbSub * pStRmbSub, + rmb_callback_func func, void *func_argv) +{ + + int iRet = 0; + iRet = + rmb_context_add_rr_rsp_mq_fifo (pStRmbSub->pStContext, + pRmbStConfig->strFifoPathForRRrsp, + pRmbStConfig->uiShmKeyForRRrsp, + pRmbStConfig->uiShmSizeForRRrsp, func, + func_argv); + if (iRet != 0) + { + return rmb_errno; + } + return 0; +} + +int rmb_sub_add_reveive_rsp_by_mq_v2 (StRmbSub * pStRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv) +{ + int iRet = 0; + + iRet = + rmb_context_add_rr_rsp_mq_fifo (pStRmbSub->pStContext, strFifoPath, + uiShmKey, uiShmSize, func, func_argv); + if (iRet != 0) + { + return rmb_errno; + } + return 0; +} + +int rmb_sub_add_reveive_rsp_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + int iRet = 0; + StRmbSub *pStRmbSub = pRmbGlobalSub; + + iRet = + rmb_context_add_rr_rsp_mq_fifo (pStRmbSub->pStContext, strFifoPath, + uiShmKey, uiShmSize, func, func_argv); + if (iRet != 0) + { + return rmb_errno; + } + return 0; +} + +/** + * Function: rmb_sub_add_reveive_req + * Description: init, sub add receive queue request package + * Return: + * 0: success + * other: failed + */ +int rmb_sub_add_reveive_req (StRmbSub * pStRmbSub, unsigned short usReqPort) +{ + + int iRet = + rmb_context_add_req_socket (pStRmbSub->pStContext, pRmbStConfig->cHostIp, + usReqPort); + if (iRet != 0) + { + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return rmb_errno; + } + return 0; +} + +int rmb_sub_add_reveive_req_by_mq (StRmbSub * pStRmbSub, + rmb_callback_func func, void *func_argv) +{ + + int iRet = 0; + + iRet = + rmb_context_add_req_mq_fifo (pStRmbSub->pStContext, + pRmbStConfig->strFifoPathForReq, + pRmbStConfig->uiShmKeyForReq, + pRmbStConfig->uiShmSizeForReq, func, + func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_req_by_mq_v2 (StRmbSub * pStRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, void *func_argv) +{ + + int iRet = 0; + + iRet = + rmb_context_add_req_mq_fifo (pStRmbSub->pStContext, strFifoPath, uiShmKey, + uiShmSize, func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_req_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + + int iRet = 0; + StRmbSub *pStRmbSub = pRmbGlobalSub; + iRet = + rmb_context_add_req_mq_fifo (pStRmbSub->pStContext, strFifoPath, uiShmKey, + uiShmSize, func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_broadcast (StRmbSub * pStRmbSub, + unsigned short usRevBroadcastPort) +{ + + int iRet = + rmb_context_add_broadcast_socket (pStRmbSub->pStContext, + pRmbStConfig->cHostIp, + usRevBroadcastPort); + if (iRet != 0) + { + rmb_errno = RMB_ERROR_INIT_UDP_FAIL; + return rmb_errno; + } + return 0; +} + +/** + * Function: rmb_sub_add_reveive_broadcast_by_mq + * Description: init, sub add receive broadcast package + * Return: + * 0: success + * other: failed + */ +int rmb_sub_add_reveive_broadcast_by_mq (StRmbSub * pStRmbSub, + rmb_callback_func func, + void *func_argv) +{ + + int iRet = 0; + + iRet = + rmb_context_add_broadcast_mq_fifo (pStRmbSub->pStContext, + pRmbStConfig->strFifoPathForBroadcast, + pRmbStConfig->uiShmKeyForBroadcast, + pRmbStConfig->uiShmSizeForBroadcast, + func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_broadcast_by_mq_v2 (StRmbSub * pStRmbSub, + const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + + int iRet = 0; + + iRet = + rmb_context_add_broadcast_mq_fifo (pStRmbSub->pStContext, strFifoPath, + uiShmKey, uiShmSize, func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_reveive_broadcast_by_mq_python (const char *strFifoPath, + const unsigned int uiShmKey, + const unsigned int uiShmSize, + rmb_callback_func func, + void *func_argv) +{ + + int iRet = 0; + StRmbSub *pStRmbSub = pRmbGlobalSub; + iRet = + rmb_context_add_broadcast_mq_fifo (pStRmbSub->pStContext, strFifoPath, + uiShmKey, uiShmSize, func, func_argv); + if (iRet != 0) + { + return -1; + } + + return 0; +} + +int rmb_sub_add_listen (StRmbSub * pStRmbSub, + const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize) +{ + if (pStRmbSub == NULL || pQueueInfo == NULL || uiQueueSize == 0) + { + LOGRMB (RMB_LOG_ERROR, + "pStRmbSub or pQueueInfo is null or uiQueueSize=%u", uiQueueSize); + return -1; + } + st_rmb_queue_info *p = pQueueInfo; + + pStRmbSub->pQueueInfo = pQueueInfo; + pStRmbSub->iQueueNum = uiQueueSize; + //pStRmbSub->uiFlagForFilter = RMB_FILTER_FLAG_FOR_SUB; + + int i = 0; + int iRet = 0; + iRet = + rmb_sub_add_listen_to_wemq (pStRmbSub, pQueueInfo, uiQueueSize, + pRmbStConfig->cConsumerDcn, + pRmbStConfig->cConsumerSysId); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "sub add listen to wemq failed, dcn=%s", + pRmbStConfig->cConsumerDcn); + return iRet; + } + + return wemq_sub_add_start_to_access (pStRmbSub); +} + +int rmb_sub_add_listen_python (const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize) +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + + return rmb_sub_add_listen (pStRmbSub, pQueueInfo, uiQueueSize); +} + +/** + * Function: rmb_sub_do_receive + * Description: add epoll + * Return: + * 0: success + * other: failed + */ +int rmb_sub_do_receive (StRmbSub * pStRmbSub, int iTimeout) +{ + int iRet = rmb_notify_epoll (pStRmbSub, iTimeout); + + return iRet; + +} + +int rmb_sub_do_receive_python () +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + int iRet = rmb_notify_epoll (pStRmbSub, 1); + + return iRet; + +} + +/** + * Function: rmb_sub_reply_msg + * Description: report message + * Return: + * 0: success + * -1: failed + */ +int rmb_sub_reply_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + RMB_CHECK_POINT_NULL (pStRmbSub, "pStRmbSub"); + RMB_CHECK_POINT_NULL (pStReceiveMsg, "pStReceiveMsg"); + RMB_CHECK_POINT_NULL (pStReplyMsg, "pStReplyMsg"); + + if (strlen (pStReceiveMsg->replyTo.cDestName) == 0) + { + LOGRMB (RMB_LOG_WARN, "pStReceiveMsg->replyTo.cDestName=%s", + pStReceiveMsg->replyTo.cDestName); + return 0; + } + + return wemq_sub_reply_msg (pStRmbSub, pStReceiveMsg, pStReplyMsg); + +} + +int rmb_sub_reply_msg_python (StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + + return rmb_sub_reply_msg (pStRmbSub, pStReceiveMsg, pStReplyMsg); +} + +/** + * Function: rmb_sub_ack_msg + * Description: ack received message + * Return: + * 0: success + * -1: failed + */ +int rmb_sub_ack_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg) +{ + RMB_CHECK_POINT_NULL (pStRmbSub, "pStRmbSub"); + RMB_CHECK_POINT_NULL (pStReceiveMsg, "pStReceiveMsg"); + + return 0; +} + +/** + * Function: rmb_sub_close + * Description:close sub + */ +int rmb_sub_close (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub is null"); + return 0; + } + + //wemq + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pStRmbSub->pStContext != NULL + && pStRmbSub->pStContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pStRmbSub->pStContext->pContextProxy; + + if (rmb_sub_send_client_goodbye_to_wemq (pStRmbSub) != 0) + { + LOGRMB (RMB_LOG_ERROR, "send sub client goodbye to wemq fail"); + } + pContextProxy->iFlagForRun = 0; + GetRmbNowLongTime (); + pContextProxy->ulGoodByeTime = pRmbStConfig->ulNowTtime; + LOGRMB (RMB_LOG_DEBUG, "pthread_join mainThreadId"); + if (pContextProxy->mainThreadId != 0) + { + pthread_join (pContextProxy->mainThreadId, NULL); + } + + LOGRMB (RMB_LOG_DEBUG, "pthread_join coThreadId"); + if (pContextProxy->coThreadId != 0) + { + pthread_join (pContextProxy->coThreadId, NULL); + } + + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsg); + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsgForRR); + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsgForBroadCast); + free (pStRmbSub->pStContext->pWemqPkg); + free (pStRmbSub->pStContext->pWemqPkgForRRAsync); + + } + } + + LOGRMB (RMB_LOG_DEBUG, "call rmb_sub_close for over"); + + return 0; +} + +int rmb_sub_close_python () +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + while (rmb_sub_check_req_mq_is_null (pStRmbSub) != 0) //本地的共享内存还有未处理完的消息 + { + rmb_sub_do_receive (pStRmbSub, 1); + } + + int ret = rmb_sub_close_v2 (pStRmbSub); + free (pStRmbSub); + return ret; +} + +/** + * Function: rmb_sub_close_v2 + * Description:close sub + */ +int rmb_sub_close_v2 (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub is null"); + return 0; + } + + //wemq + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pStRmbSub->pStContext != NULL + && pStRmbSub->pStContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pStRmbSub->pStContext->pContextProxy; + + pContextProxy->iFlagForRun = 0; + GetRmbNowLongTime (); + pContextProxy->ulGoodByeTime = pRmbStConfig->ulNowTtime; + LOGRMB (RMB_LOG_DEBUG, "pthread_join mainThreadId"); + if (pContextProxy->mainThreadId != 0) + { + pthread_join (pContextProxy->mainThreadId, NULL); + } + + LOGRMB (RMB_LOG_DEBUG, "pthread_join coThreadId"); + if (pContextProxy->coThreadId != 0) + { + pthread_join (pContextProxy->coThreadId, NULL); + } + + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsg); + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsgForRR); + rmb_msg_free (pStRmbSub->pStContext->pReceiveWemqMsgForBroadCast); + free (pStRmbSub->pStContext->pWemqPkg); + free (pStRmbSub->pStContext->pWemqPkgForRRAsync); + } + } + + LOGRMB (RMB_LOG_DEBUG, "call rmb_sub_close for over"); + + return 0; +} + +int rmb_sub_send_client_goodbye_to_wemq (StRmbSub * pRmbSub) +{ + RMB_CHECK_POINT_NULL (pRmbSub, "pStRmbSub"); + + stContextProxy *pContextProxy = pRmbSub->pStContext->pContextProxy; + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_CLIENT_GOODBYE; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return -2; + } + //add command + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (CLIENT_GOODBYE_REQUEST)); + //add seq + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + //add code + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "header is null"); + json_object_put (jsonHeader); + return -2; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%u, %s", + stThreadMsg.m_iHeaderLen, header_str) stThreadMsg.m_pHeader = + (char *) malloc ((stThreadMsg.m_iHeaderLen + 1) * sizeof (char)); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for stThreadMsg.m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + stThreadMsg.m_iBodyLen = 0; + stThreadMsg.m_pBody = NULL; + pthread_mutex_lock (&pContextProxy->goodByeMutex); + int iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error,iRet=%d!\n", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return rmb_errno; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->goodByeTimeOut) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->goodByeTimeOut) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForGoodBye = 0; + + if (pContextProxy->iFlagForGoodBye == 0) + { + pthread_cond_timedwait (&pContextProxy->goodByeCond, + &pContextProxy->goodByeMutex, &timeout); + } + pthread_mutex_unlock (&pContextProxy->goodByeMutex); + + if (pContextProxy->iFlagForGoodBye != 1) + { + LOGRMB (RMB_LOG_ERROR, "send sub client goodBye timeout!"); + rmb_errno = RMB_ERROR_CLIENT_GOODBYE_TIMEOUT; + return rmb_errno; + } + + LOGRMB (RMB_LOG_DEBUG, "send and recv sub client goodBye succ"); + + return 0; +} + +/* +Function: rmb_sub_stop_receive +Description:rmb_sub停止接受queue消息 +* Return: +* 见rmb_errno.h文件 +*/ +int rmb_sub_stop_receive (StRmbSub * pStRmbSub) +{ + int iRet = 0; + if (pRmbStConfig->iConnWemq == 1 || pRmbStConfig->iApiLogserverSwitch == 1) + { + if (pStRmbSub->pStContext != NULL + && pStRmbSub->pStContext->pContextProxy != NULL) + { + stContextProxy *pContextProxy = pStRmbSub->pStContext->pContextProxy; + if (rmb_sub_send_client_goodbye_to_wemq (pStRmbSub) == 0) + { + //pContextProxy->iFlagForRun = 0; + return 0; + } + else + { + LOGRMB (RMB_LOG_ERROR, "send client goodbye to wemq fail"); + //pContextProxy->iFlagForRun = 0; + return -1; + } + } + else + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub->pStContext null"); + return -2; + } + } + return 0; +} + +/* +Function: rmb_sub_stop_receive_python +Description:rmb_sub停止接受queue消息 +* Return: +* 见rmb_errno.h文件 +*/ +int rmb_sub_stop_receive_python () +{ + StRmbSub *pStRmbSub = pRmbGlobalSub; + + return rmb_sub_stop_receive (pStRmbSub); +} + +//add 2015-02-10 +StMqInfo *rmb_sub_get_mq_by_type (StRmbSub * stRmbSub, int iType) +{ + return stRmbSub->pStContext->fifoMq.mqIndex[iType]; +} + +StMqInfo *rmb_sub_get_receve_req_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) req_mq_index); +} + +StMqInfo *rmb_sub_get_rr_rsp_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) rr_rsp_mq_index); +} + +StMqInfo *rmb_sub_get_broadcast_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) broadcast_mq_index); +} + +StMqInfo *rmb_sub_get_receve_rsp_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) rr_rsp_mq_index); +} + +StMqInfo *rmb_sub_get_receve_broadcast_mq (StRmbSub * stRmbSub) +{ + if (stRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "stRmb==NULL"); + return NULL; + } + return rmb_sub_get_mq_by_type (stRmbSub, (int) broadcast_mq_index); +} + +int rmb_sub_get_fd (StMqInfo * pMqInfo) +{ + RMB_CHECK_POINT_NULL (pMqInfo, "pMqInfo"); + + return pMqInfo->fifo->iFd; +} + +int rmb_sub_receive_from_mq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ + RMB_CHECK_POINT_NULL (pMqInfo, "pMqInfo"); + + return rmb_notify_dequeue (pMqInfo, buf, uiBufSize, pDataLen); +} + +int rmb_sub_try_receive_from_mq (StMqInfo * pMqInfo, char *buf, + const unsigned int uiBufSize, + unsigned int *pDataLen) +{ + RMB_CHECK_POINT_NULL (pMqInfo, "pMqInfo"); + + return rmb_notify_try_dequeue (pMqInfo, buf, uiBufSize, pDataLen); +} + +/* +Function: rmb_sub_check_mq_is_null +Description:校验所有队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int rmb_sub_check_mq_is_null (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub==NULL"); + return NULL; + } + int result = rmb_sub_check_req_mq_is_null (pStRmbSub) + && rmb_sub_check_rr_rsp_mq_is_null (pStRmbSub) + && rmb_sub_check_broadcast_mq_is_null (pStRmbSub); + return result; +} + +/* +Function: rmb_sub_check_req_mq_is_null +Description:校验是否请求队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int rmb_sub_check_req_mq_is_null (StRmbSub * pStRmbSub) +{ + StMqInfo *p = rmb_sub_get_receve_req_mq (pStRmbSub); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/* +Function: rmb_sub_check_rr_rsp_mq_is_null +Description:校验rr_rsp队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int rmb_sub_check_rr_rsp_mq_is_null (StRmbSub * pStRmbSub) +{ + StMqInfo *p = rmb_sub_get_rr_rsp_mq (pStRmbSub); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/* +Function: rmb_sub_check_broadcast_mq_is_null +Description:校验broadcast队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int rmb_sub_check_broadcast_mq_is_null (StRmbSub * pStRmbSub) +{ + StMqInfo *p = rmb_sub_get_broadcast_mq (pStRmbSub); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////////////// +/** + * Description: add bind to wemq + * Return: + * 0: success + * -1: arg error + * -2: error + * json: + * send: + * headerJson={"code":0,"seq":"1333580037","command":"SUBSCRIBE_REQUEST"} + * |bodyJson={"topicList":["PRX-e-10030002-05-3","PRX-e-10020002-02-2","PRX-s-10000002-01-0","PRX-e-10020002-06-2"]} + * 例如: + * success: -- code为0 + * headerJson={"code":0,"seq":"1333580037","command":"SUBSCRIBE_RESPONSE", "message":"ok"}|bodyJson=null + * failed: -- code非0 + headerJson={"code":0,"seq":"1333580037","command":"SUBSCRIBE_RESPONSE", "message":"no topic route"}|bodyJson=null + * + */ +int rmb_sub_add_listen_to_wemq (StRmbSub * pRmbSub, + const st_rmb_queue_info * pQueueInfo, + unsigned int uiQueueSize, const char *cDcn, + const char *cSysId) +{ + RMB_CHECK_POINT_NULL (pRmbSub, "pStRmbSub"); + RMB_CHECK_POINT_NULL (pRmbSub->pStContext, "pStRmbSub->pStContext"); + RMB_CHECK_POINT_NULL (pRmbSub->pStContext->pContextProxy, + "pStRmbSub->pStContext->pContextProxy"); + RMB_CHECK_POINT_NULL (cDcn, "cDcn"); + RMB_CHECK_POINT_NULL (cSysId, "cSysId"); + + stContextProxy *pContextProxy = pRmbSub->pStContext->pContextProxy; + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_ADD_LISTEN; + WEMQJSON *jsonTopicList = json_object_new_array (); + st_rmb_queue_info *p = pQueueInfo; + int i; + char cBroadcastDcn[10] = "000"; + for (i = 0; i < uiQueueSize; i++) + { + char cTopic[200] = { 0 }; + char serviceOrEvent = (*(p->cServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", cDcn, serviceOrEvent, + p->cServiceId, p->cScenarioId, *(p->cServiceId + 3)); + json_object_array_add (jsonTopicList, json_object_new_string (cTopic)); + //自动监听广播topic + if (serviceOrEvent == 'e') + { + memset (cTopic, 0x00, sizeof (cTopic)); + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", cBroadcastDcn, + serviceOrEvent, p->cServiceId, p->cScenarioId, + *(p->cServiceId + 3)); + json_object_array_add (jsonTopicList, json_object_new_string (cTopic)); + } + p += 1; + } + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonHeader failed"); + return -1; + } + + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (SUBSCRIBE_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonBody failed"); + json_object_put (jsonHeader); + json_object_put (jsonTopicList); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_TOPIC_LIST_JSON, jsonTopicList); + + const char *header_str = json_object_get_string (jsonHeader); + + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_get_string for header is null"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -2; + } + stThreadMsg.m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_INFO, "Gen thread msg header succ, len=%d, %s", + stThreadMsg.m_iHeaderLen, header_str); + stThreadMsg.m_pHeader = + (char *) malloc (stThreadMsg.m_iHeaderLen * sizeof (char) + 1); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for m_pHeader failed, errno=%d", errno); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + strncpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + json_object_put (jsonBody); + return -1; + } + + stThreadMsg.m_iBodyLen = strlen (body_str); + stThreadMsg.m_pBody = + (char *) malloc (stThreadMsg.m_iBodyLen * sizeof (char) + 1); + if (stThreadMsg.m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonBody); + return -1; + } + memcpy (stThreadMsg.m_pBody, body_str, stThreadMsg.m_iBodyLen); + stThreadMsg.m_pBody[stThreadMsg.m_iBodyLen] = '\0'; + + json_object_put (jsonBody); + pthread_mutex_lock (&pContextProxy->regMutex); + int iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error,iRet=%d!\n", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return -3; + } + + struct timeval nowTimeVal; + gettimeofday (&nowTimeVal, NULL); + struct timespec timeout; + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) % 1000) * 1000 * 1000; + + pContextProxy->iFlagForReg = 0; + pContextProxy->iResultForReg = -1; + if (pContextProxy->iFlagForReg == 0) + { + pthread_cond_timedwait (&pContextProxy->regCond, &pContextProxy->regMutex, + &timeout); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + + if (pContextProxy->iFlagForReg == 1 && pContextProxy->iResultForReg != 0) + { + LOGRMB (RMB_LOG_ERROR, "add listen failed,iRet=%d,dcn=%s", + pContextProxy->iResultForReg, cDcn); + rmb_errno = RMB_ERROR_WORKER_REGISTER_ERROR; + return rmb_errno; + } + + if (pContextProxy->iFlagForReg != 1) + { + LOGRMB (RMB_LOG_ERROR, "add listen timeout!dcn=%s", cDcn); + rmb_errno = RMB_ERROR_WORKER_REGISTER_ERROR; + return rmb_errno; + } + + LOGRMB (RMB_LOG_DEBUG, "add listen succ!dcn=%s", cDcn); + //cache sub topic; + p = pQueueInfo; + for (i = 0; i < uiQueueSize; i++) + { + StWemqTopicProp stTopicProp; + memset (&stTopicProp, 0, sizeof (stTopicProp)); + stTopicProp.flag = 0; + strncpy (stTopicProp.cServiceId, p->cServiceId, strlen (p->cServiceId)); + stTopicProp.cServiceId[8] = '\0'; + strncpy (stTopicProp.cScenario, p->cScenarioId, strlen (p->cScenarioId)); + stTopicProp.cScenario[2] = '\0'; + wemq_topic_list_add_node (&pContextProxy->stTopicList, &stTopicProp); + p += 1; + } + + return 0; +} + +int wemq_sub_add_start_to_access (StRmbSub * pStRmbSub) +{ + if (pStRmbSub == NULL || pStRmbSub->pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub or pStRmbSub->pStContext is null"); + return -1; + } + + stContextProxy *pContextProxy = pStRmbSub->pStContext->pContextProxy; + if (pContextProxy == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmbSub->pStContext->pContextProxy is null"); + return -1; + } + + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_START; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return -2; + } + //add command + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (LISTEN_REQUEST)); + //add seq + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + //add code + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "header is null"); + json_object_put (jsonHeader); + return -2; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%u, %s", + stThreadMsg.m_iHeaderLen, header_str); + stThreadMsg.m_pHeader = + (char *) malloc ((stThreadMsg.m_iHeaderLen + 1) * sizeof (char)); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for stThreadMsg.m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + stThreadMsg.m_iBodyLen = 0; + stThreadMsg.m_pBody = NULL; + + int iRet = 0; + struct timeval nowTimeVal; + struct timespec timeout; + pthread_mutex_lock (&pContextProxy->regMutex); + iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put for listen comman error"); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + return -3; + } + + gettimeofday (&nowTimeVal, NULL); + timeout.tv_sec = + nowTimeVal.tv_sec + (nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) / 1000; + timeout.tv_nsec = + ((nowTimeVal.tv_usec / 1000 + + pRmbStConfig->iNormalTimeout) % 1000) * 1000 * 1000; + + pContextProxy->iResultForReg = -1; + pContextProxy->iFlagForReg = 0; + if (pContextProxy->iFlagForReg == 0) + { + pthread_cond_timedwait (&pContextProxy->regCond, &pContextProxy->regMutex, + &timeout); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + + switch (pContextProxy->iResultForReg) + { + case RMB_CODE_TIME_OUT: + LOGRMB (RMB_LOG_ERROR, "send start command timeout"); + return -6; + case RMB_CODE_SUSS: + LOGRMB (RMB_LOG_INFO, "send start command to access succ"); + return 0; + case RMB_CODE_OTHER_FAIL: + LOGRMB (RMB_LOG_ERROR, "send start command failed,iRet=%d", + pContextProxy->iResultForReg); + return -4; + case RMB_CODE_AUT_FAIL: + LOGRMB (RMB_LOG_ERROR, "send start command authentication failed,iRet=%d", + pContextProxy->iResultForReg); + return -5; + default: + return 0; + } + +} + +int wemq_sub_reply_msg (StRmbSub * pStRmbSub, StRmbMsg * pStReceiveMsg, + StRmbMsg * pStReplyMsg) +{ + if (pStRmbSub == NULL || pStReceiveMsg == NULL || pStReplyMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmb or pStReceiveMsg or pStReplyMsg is null"); + return -1; + } + + memcpy (&pStReplyMsg->sysHeader, &pStReceiveMsg->sysHeader, + sizeof (pStReceiveMsg->sysHeader)); + memcpy (&pStReplyMsg->dest, &pStReceiveMsg->replyTo, + sizeof (pStReceiveMsg->replyTo)); + if (strlen (pStReplyMsg->dest.cDestName) == 0) + { + LOGRMB (RMB_LOG_ERROR, "receiveMsg has no replyTo, can't reply!"); + return -2; + } + LOGRMB (RMB_LOG_DEBUG, "receive msg property: %s", + pStReceiveMsg->sysHeader.cProperty); + memcpy (&pStReplyMsg->sysHeader.cProperty, + &pStReceiveMsg->sysHeader.cProperty, + sizeof (pStReceiveMsg->sysHeader.cProperty)); + + //serviceId + memcpy (pStReplyMsg->strServiceId, pStReceiveMsg->strServiceId, + sizeof (pStReceiveMsg->strServiceId)); + //scenarioId + memcpy (pStReplyMsg->strScenarioId, pStReceiveMsg->strScenarioId, + sizeof (pStReceiveMsg->strScenarioId)); + //dcn + memcpy (pStReplyMsg->strTargetDcn, pStReceiveMsg->strTargetDcn, + sizeof (pStReceiveMsg->strTargetDcn)); + //organization + memcpy (pStReplyMsg->strTargetOrgId, pStReceiveMsg->strTargetOrgId, + sizeof (pStReceiveMsg->strTargetOrgId)); + //ttl + pStReplyMsg->ulMsgLiveTime = pStReceiveMsg->ulMsgLiveTime; + + strncpy (pStReplyMsg->cCorrId, pStReceiveMsg->cCorrId, + sizeof (pStReceiveMsg->cCorrId)); + pStReplyMsg->iCorrLen = pStReceiveMsg->iCorrLen; + pStReplyMsg->cApiType = C_TYPE_WEMQ; + pStReplyMsg->cLogicType = RSP_PKG_OUT_WEMQ; + GetRmbNowLongTime (); + pStReplyMsg->sysHeader.ulReplyTime = pRmbStConfig->ulNowTtime; + + StContext *pStContext = pStRmbSub->pStContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_REPLY; + int iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pStReplyMsg, + 3000); + //LOGRMB(RMB_LOG_DEBUG, "encode succ header %s, body %s\n",stThreadMsg.m_pHeader, stThreadMsg.m_pBody); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!\n"); + return iRet; + } + + iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "sub reply wemq_kfifo_put error", pStReplyMsg); + return rmb_errno; + } + + return 0; +} + +int wemq_sub_ack_msg (StRmbSub * pStRmbSub, StRmbMsg * pStAckMsg) +{ + if (pStRmbSub == NULL || pStAckMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStRmb or pStReplyMsg is null"); + return -1; + } + + if (pStAckMsg->cPkgType == RR_TOPIC_PKG) + { + return 0; + } + + LOGRMB (RMB_LOG_DEBUG, "receive msg property: %s", + pStAckMsg->sysHeader.cProperty); + + StContext *pStContext = pStRmbSub->pStContext; + pStContext->uiPkgLen = MAX_LENTH_IN_A_MSG; + stContextProxy *pContextProxy = pStContext->pContextProxy; + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_SEND_MSG_ACK; + int iRet = + rmb_pub_encode_thread_msg (stThreadMsg.m_iCmd, &stThreadMsg, pStAckMsg, + 3000); + //LOGRMB(RMB_LOG_DEBUG, "encode succ header %s, body %s\n",stThreadMsg.m_pHeader, stThreadMsg.m_pBody); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_pub_encode_thread_msg error!\n"); + return iRet; + } + + iRet = wemq_kfifo_put (&pContextProxy->subFifo, stThreadMsg); + if (iRet <= 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_kfifo_put error!iRet=%d", iRet); + rmb_errno = RMB_ERROR_WORKER_PUT_FIFO_ERROR; + rmb_send_log_for_error (pStContext->pContextProxy, + RMB_ERROR_WORKER_PUT_FIFO_ERROR, + "sub ack wemq_kfifo_put error", pStAckMsg); + return rmb_errno; + } + + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_udp.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_udp.c new file mode 100644 index 0000000000..76fd187ed1 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_udp.c @@ -0,0 +1,383 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "rmb_udp.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int udp_get_socket (const char *host, const char *serv, socklen_t * addrlenp) +{ + int iUDPSocket; + int iRet; + + struct addrinfo hints; + struct addrinfo *res, *ressave; + + memset (&hints, 0, sizeof (struct addrinfo)); + hints.ai_flags = AI_PASSIVE; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + if ((iRet = getaddrinfo (host, serv, &hints, &res)) != 0) + { + return -1; + } + ressave = res; + + do + { + iUDPSocket = socket (res->ai_family, res->ai_socktype, res->ai_protocol); + if (iUDPSocket < 0) + continue; /* error, try next one */ + + if (bind (iUDPSocket, res->ai_addr, res->ai_addrlen) == 0) + break; /* success */ + + close (iUDPSocket); /* bind error, close and try next one */ + } + while ((res = res->ai_next) != NULL); + + if (res == NULL) /* errno from final socket() or bind() */ + return -1; + //err_sys("udp_server error for %s, %s", host, serv); + + if (addrlenp) + *addrlenp = res->ai_addrlen; /* return size of protocol address */ + + freeaddrinfo (ressave); + + if (iUDPSocket < 0) + { + return -1; + //err_sys("UDP_GetSocket error : %s", strerror(errno)); + } + return iUDPSocket; +} + +int udp_server (const char *pszHost, unsigned short usPort) +{ + int udpsock; + struct hostent *hostinfo; + struct in_addr *addp; + struct sockaddr_in sockname; + + memset ((char *) &sockname, 0, sizeof (sockname)); + if (pszHost == NULL) + { + hostinfo = NULL; + } + else if ((hostinfo = gethostbyname (pszHost)) == NULL) + { + //err_msg("Cannot find %s - %s",pszHost,strerror(errno)); + return -1; + } + + udpsock = socket (AF_INET, SOCK_DGRAM, 0); + if (udpsock < 0) + { + //err_msg("Error opening socket - %s",strerror(errno)); + return -1; + } + //setsockopt(udpsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + if (hostinfo != NULL) + { + addp = (struct in_addr *) *(hostinfo->h_addr_list); + sockname.sin_addr = *addp; + } + else + { + sockname.sin_addr.s_addr = INADDR_ANY; + } + sockname.sin_family = AF_INET; + sockname.sin_port = htons (usPort); + + if ((bind (udpsock, (struct sockaddr *) &sockname, sizeof (sockname))) == + -1) + { + close (udpsock); + //err_msg("Cannot bind port %i at %s -%s",usPort,pszHost,strerror(errno)); + return -1; + } + + return (udpsock); +} + +int check_socket (int iSocket, fd_set * pStReadFds, int iNfd) +{ + struct timeval stTimeVal; + + FD_ZERO (pStReadFds); + FD_SET (iSocket, pStReadFds); + stTimeVal.tv_sec = 0; + stTimeVal.tv_usec = 5000; + + if (select (iNfd, pStReadFds, NULL, NULL, &stTimeVal) > 0) + { + return 0; + } + return -1; +} + +int check_socket_with_timeout (int iSocket, fd_set * pStReadFds, int iNfd, + int sec, int usec) +{ + struct timeval stTimeVal; + + FD_ZERO (pStReadFds); + FD_SET (iSocket, pStReadFds); + stTimeVal.tv_sec = sec; + stTimeVal.tv_usec = usec; + + if (select (iNfd, pStReadFds, NULL, NULL, &stTimeVal) > 0) + { + return 0; + } + return -1; +} + +int check_and_process_socket (int iSocket, fd_set * pStReadFds, char *cPkgBuf, + const unsigned int uiMaxLen, + unsigned int *pPkgLen) +{ + if (FD_ISSET (iSocket, pStReadFds)) + { + struct sockaddr_in stFromAddr; + socklen_t iAddrLength = sizeof (stFromAddr); + *pPkgLen = 0; + //LOGSYS(RMB_LOG_DEBUG, " sizeof(cPkgBuf)=%lu", sizeof(cPkgBuf)); + + int iRet = recvfrom (iSocket, cPkgBuf, uiMaxLen, + 0, (struct sockaddr *) &stFromAddr, &iAddrLength); + if (iRet > 0) + { + *pPkgLen = iRet; + } + return iRet; + } + return 0; +} + +int tcp_nodelay (int iSockfd) +{ + int i; + + if ((i = fcntl (iSockfd, F_GETFL, 0)) == -1) + return (-1); + else if (fcntl (iSockfd, F_SETFL, i | FNDELAY) == -1) + return (-1); + return 0; +} + +int get_host_name (char *hostName, unsigned int uiHostNameLen) +{ + struct hostent *host; //���������Ϣ +// while () +// { +// +// } + + if ((host = gethostent ()) == NULL) + { + LOGRMB (RMB_LOG_ERROR, " fail to get host's information"); + return -1; + } + strncpy (hostName, host->h_name, uiHostNameLen); + + while ((host = gethostent ()) != NULL) + { + } + endhostent (); + //LOGSYS(LOG_ERROR, "%s hostName: %s,%s,uiHostName=%u" , __func__, hostName, host->h_name, uiHostNameLen); + return 0; +} + +int get_local_ip (char *addr, unsigned int uiAddrLen) +{ + int i = 0; + int sockfd; + struct ifconf ifconf; + char buf[512]; + struct ifreq *ifreq; + char *ip; + + ifconf.ifc_len = 512; + ifconf.ifc_buf = buf; + + if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) + { + return -1; + } + ioctl (sockfd, SIOCGIFCONF, &ifconf); + close (sockfd); + + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + + return -1; +} + +/** + * 2.0.10版本增加,逻辑为: + * 通过获取环境变量networkInterface的值,来获取对应的ip + * 如果失败,则返回默认值 + * 默认获取方式: bond1 > eth1 > eth0 + */ +int get_local_ip_v2 (char *addr, unsigned int uiAddrLen) +{ + char *val = NULL; + + val = getenv ("networkInterface"); + + int i = 0; + int sockfd; + struct ifconf ifconf; + char buf[512]; + struct ifreq *ifreq; + char *ip; + + ifconf.ifc_len = 512; + ifconf.ifc_buf = buf; + + if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) + { + return -1; + } + ioctl (sockfd, SIOCGIFCONF, &ifconf); + close (sockfd); + + //first getenv + if (val != NULL) + { + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + if (strcmp (ifreq->ifr_name, val) != 0) + { + ifreq++; + continue; + } + + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + } + + //bond1 + { + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + if (strcmp (ifreq->ifr_name, "bond1") != 0) + { + ifreq++; + continue; + } + + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + } + + //eth1 + { + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + if (strcmp (ifreq->ifr_name, "eth1") != 0) + { + ifreq++; + continue; + } + + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + } + + ifreq = (struct ifreq *) buf; + for (i = (ifconf.ifc_len / sizeof (struct ifreq)); i > 0; i--) + { + ip = inet_ntoa (((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr); + + if (strcmp (ip, "127.0.0.1") == 0) + { + ifreq++; + continue; + } + + strncpy (addr, ip, uiAddrLen); + //LOGSYS(LOG_ERROR, "%s HostIp: %s,%s,len=%u" , __func__, addr,ip, uiAddrLen); + return 0; + } + + return -1; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/rmb_vector.c b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_vector.c new file mode 100644 index 0000000000..5e0b35b84f --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/rmb_vector.c @@ -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. + +#include "rmb_vector.h" +#include +#include +#include +#include +#include "rmb_msg.h" + +void Init (Array * this) +{ + this->Input = _input; + + this->get_array_size = _get_size; + this->return_index_value = _return_index_value; + + this->Constructor = _constructor; + this->Destructor = _destructor; + this->Constructor (this); +} + +void _constructor (Array * this) +{ + this->size = 0; + this->max_size = MAX_SIZE_PER_TIME; + this->Data = (DataType *) malloc (this->max_size * sizeof (DataType)); + memset (this->Data, 0x00, this->max_size * sizeof (DataType)); +} + +void _input (DataType data, Array * this) +{ + int i; + DataType *ptr; + + ptr = + (DataType *) malloc ((this->max_size + MAX_SIZE_PER_TIME) * + sizeof (DataType)); + memset (ptr, 0x00, + (this->max_size + MAX_SIZE_PER_TIME) * sizeof (DataType)); + for (i = 0; i < this->max_size; i++) + ptr[i] = this->Data[i]; + free (this->Data); + this->Data = ptr; + + snprintf (this->Data[this->max_size].unique_id, sizeof (data.unique_id), + "%s", data.unique_id); + snprintf (this->Data[this->max_size].biz_seq, sizeof (data.biz_seq), "%s", + data.biz_seq); + this->Data[this->max_size].flag = 1; + this->Data[this->max_size].timeStamp = data.timeStamp; + this->Data[this->max_size].timeout = data.timeout; + this->max_size += MAX_SIZE_PER_TIME; +} + +int _get_size (Array * this) +{ + assert (this != NULL); + return this->max_size; +} + +DataType _return_index_value (Array * this, int index) +{ + assert (this != NULL); + return (this->Data[index]); +} + +void _destructor (Array * this) +{ + assert (this != NULL); + free (this->Data); +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_fifo.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_fifo.c new file mode 100644 index 0000000000..e8b806129d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_fifo.c @@ -0,0 +1,350 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* + * A generic kernel FIFO implementation + * + * Copyright (C) 2009/2010 Stefani Seibold + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +/* +#include +#include +#include +#include +#include +#include +#include +*/ +//#include "wemq_fifo.h" +#include "rmb_define.h" +#define min(x,y) ({\ + typeof(x) _x = (x);\ + typeof(y) _y = (y);\ + (void)(&_x == &_y);\ + _x < _y ? _x : _y;}) +#define max(x,y) ({\ + typeof(x) _x = (x);\ + typeof(y) _y = (y);\ + (void)(&_x == &_y);\ + _x > _y ? _x : _y;}) +/* + * internal helper to calculate the unused elements in a fifo + */ +static inline unsigned int wemq_kfifo_unused (struct __wemq_kfifo *fifo) +{ + return (fifo->mask + 1) - (fifo->in - fifo->out); +} + +int __wemq_kfifo_alloc (struct __wemq_kfifo *fifo, unsigned int size, + size_t esize) +{ + /* + * round down to the next power of 2, since our 'let the indices + * wrap' technique works only in this case. + */ + size = roundup_pow_of_two (size); + + fifo->in = 0; + fifo->out = 0; + fifo->esize = esize; + + if (size < 2) + { + fifo->data = NULL; + fifo->mask = 0; + return -KFIFO_EINVAL; + } + + fifo->data = malloc (size * esize); + + if (!fifo->data) + { + fifo->mask = 0; + return -KFIFO_ENOMEM; + } + fifo->mask = size - 1; + + return 0; +} + +////EXPORT_SYMBOL(__wemq_kfifo_alloc); + +void __wemq_kfifo_free (struct __wemq_kfifo *fifo) +{ + free (fifo->data); + fifo->in = 0; + fifo->out = 0; + fifo->esize = 0; + fifo->data = NULL; + fifo->mask = 0; +} + +////EXPORT_SYMBOL(__wemq_kfifo_free); + +int __wemq_kfifo_init (struct __wemq_kfifo *fifo, void *buffer, + unsigned int size, size_t esize) +{ + size /= esize; + + size = roundup_pow_of_two (size); + + fifo->in = 0; + fifo->out = 0; + fifo->esize = esize; + fifo->data = buffer; + + if (size < 2) + { + fifo->mask = 0; + return -KFIFO_EINVAL; + } + fifo->mask = size - 1; + + return 0; +} + +//EXPORT_SYMBOL(__wemq_kfifo_init); + +static void wemq_kfifo_copy_in (struct __wemq_kfifo *fifo, const void *src, + unsigned int len, unsigned int off) +{ + unsigned int size = fifo->mask + 1; + unsigned int esize = fifo->esize; + unsigned int l; + + off &= fifo->mask; + if (esize != 1) + { + off *= esize; + size *= esize; + len *= esize; + } + l = min (len, size - off); + + memcpy (fifo->data + off, src, l); + memcpy (fifo->data, src + l, len - l); + /* + * make sure that the data in the fifo is up to date before + * incrementing the fifo->in index counter + */ + //smp_wmb(); +} + +unsigned int __wemq_kfifo_in (struct __wemq_kfifo *fifo, + const void *buf, unsigned int len) +{ + unsigned int l; + + l = wemq_kfifo_unused (fifo); + if (len > l) + len = l; + + wemq_kfifo_copy_in (fifo, buf, len, fifo->in); + fifo->in += len; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_in); + +static void wemq_kfifo_copy_out (struct __wemq_kfifo *fifo, void *dst, + unsigned int len, unsigned int off) +{ + unsigned int size = fifo->mask + 1; + unsigned int esize = fifo->esize; + unsigned int l; + + off &= fifo->mask; + if (esize != 1) + { + off *= esize; + size *= esize; + len *= esize; + } + l = min (len, size - off); + + memcpy (dst, fifo->data + off, l); + memcpy (dst + l, fifo->data, len - l); + /* + * make sure that the data is copied before + * incrementing the fifo->out index counter + */ + //smp_wmb(); +} + +unsigned int __wemq_kfifo_out_peek (struct __wemq_kfifo *fifo, + void *buf, unsigned int len) +{ + unsigned int l; + + l = fifo->in - fifo->out; + if (len > l) + len = l; + + wemq_kfifo_copy_out (fifo, buf, len, fifo->out); + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_out_peek); + +unsigned int __wemq_kfifo_out (struct __wemq_kfifo *fifo, + void *buf, unsigned int len) +{ + len = __wemq_kfifo_out_peek (fifo, buf, len); + fifo->out += len; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_out); + +unsigned int __wemq_kfifo_max_r (unsigned int len, size_t recsize) +{ + unsigned int max = (1 << (recsize << 3)) - 1; + + if (len > max) + return max; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_max_r); + +#define __WEMQ_KFIFO_PEEK(data, out, mask) \ + ((data)[(out) & (mask)]) +/* + * __wemq_kfifo_peek_n internal helper function for determinate the length of + * the next record in the fifo + */ +static unsigned int __wemq_kfifo_peek_n (struct __wemq_kfifo *fifo, + size_t recsize) +{ + unsigned int l; + unsigned int mask = fifo->mask; + unsigned char *data = fifo->data; + + l = __WEMQ_KFIFO_PEEK (data, fifo->out, mask); + + if (--recsize) + l |= __WEMQ_KFIFO_PEEK (data, fifo->out + 1, mask) << 8; + + return l; +} + +#define __WEMQ_KFIFO_POKE(data, in, mask, val) \ + ( \ + (data)[(in) & (mask)] = (unsigned char)(val) \ + ) + +/* + * __wemq_kfifo_poke_n internal helper function for storeing the length of + * the record into the fifo + */ +static void __wemq_kfifo_poke_n (struct __wemq_kfifo *fifo, unsigned int n, + size_t recsize) +{ + unsigned int mask = fifo->mask; + unsigned char *data = fifo->data; + + __WEMQ_KFIFO_POKE (data, fifo->in, mask, n); + + if (recsize > 1) + __WEMQ_KFIFO_POKE (data, fifo->in + 1, mask, n >> 8); +} + +unsigned int __wemq_kfifo_len_r (struct __wemq_kfifo *fifo, size_t recsize) +{ + return __wemq_kfifo_peek_n (fifo, recsize); +} + +//EXPORT_SYMBOL(__wemq_kfifo_len_r); + +unsigned int __wemq_kfifo_in_r (struct __wemq_kfifo *fifo, const void *buf, + unsigned int len, size_t recsize) +{ + if (len + recsize > wemq_kfifo_unused (fifo)) + return 0; + + __wemq_kfifo_poke_n (fifo, len, recsize); + + wemq_kfifo_copy_in (fifo, buf, len, fifo->in + recsize); + fifo->in += len + recsize; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_in_r); + +static unsigned int wemq_kfifo_out_copy_r (struct __wemq_kfifo *fifo, + void *buf, unsigned int len, + size_t recsize, unsigned int *n) +{ + *n = __wemq_kfifo_peek_n (fifo, recsize); + + if (len > *n) + len = *n; + + wemq_kfifo_copy_out (fifo, buf, len, fifo->out + recsize); + return len; +} + +unsigned int __wemq_kfifo_out_peek_r (struct __wemq_kfifo *fifo, void *buf, + unsigned int len, size_t recsize) +{ + unsigned int n; + + if (fifo->in == fifo->out) + return 0; + + return wemq_kfifo_out_copy_r (fifo, buf, len, recsize, &n); +} + +//EXPORT_SYMBOL(__wemq_kfifo_out_peek_r); + +unsigned int __wemq_kfifo_out_r (struct __wemq_kfifo *fifo, void *buf, + unsigned int len, size_t recsize) +{ + unsigned int n; + + if (fifo->in == fifo->out) + return 0; + + len = wemq_kfifo_out_copy_r (fifo, buf, len, recsize, &n); + fifo->out += n + recsize; + return len; +} + +//EXPORT_SYMBOL(__wemq_kfifo_out_r); + +void __wemq_kfifo_skip_r (struct __wemq_kfifo *fifo, size_t recsize) +{ + unsigned int n; + + n = __wemq_kfifo_peek_n (fifo, recsize); + fifo->out += n + recsize; +} + +//EXPORT_SYMBOL(__wemq_kfifo_skip_r); diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_proto.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_proto.c new file mode 100644 index 0000000000..74c79aba74 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_proto.c @@ -0,0 +1,748 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "common.h" +#include "wemq_proto.h" + +unsigned long long htonll_z (unsigned long long host) +{ + union64HN u; + u.src[0] = htonl (host >> 32); + u.src[1] = htonl (host & 0xFFFFFFFF); + return u.dest; +} + +unsigned long long ntohll_z (unsigned long long net) +{ + union64HN u; + u.src[0] = ntohl (net >> 32); + u.src[1] = ntohl (net & 0xFFFFFFFF); + return u.dest; +} + +//***************************0x01 心跳************************** +//请求 + +int GetStHeartBeatReqBaseLegth () +{ + return sizeof (int) + sizeof (unsigned int) + sizeof (char); +} + +int GetStHeartBeatReqLegth (const StHeartBeatReq * pReq) +{ + return GetStHeartBeatReqBaseLegth () + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeStHeartBeatReq (char *buf, int *pBufLen, + const StHeartBeatReq * pReq) +{ + if (*pBufLen < GetStHeartBeatReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetStHeartBeatReqLegth (pReq); + ENCODE_INT (buf, pReq->pid); + ENCODE_INT (buf, pReq->uiCount); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +//return -1,空间不足 +//return -2,buf长度不够 +int DecodeHeartBeatReq (StHeartBeatReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetStHeartBeatReqBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->pid, buf, &iTmpLen); + DECODE_INT (pReq->uiCount, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +//回复 + +int GetStHeartBeatRspBaseLegth () +{ + return 3 * sizeof (unsigned int) + sizeof (char); +} + +int GetStHeartBeatRspLegth (const StHeartBeatRsp * pRsp) +{ + return GetStHeartBeatRspBaseLegth () + pRsp->cReseveLength; +} + +//return -1.空间不足 +int EncodeStHeartBeatRsp (char *buf, int *pBufLen, + const StHeartBeatRsp * pRsp) +{ + if (*pBufLen < GetStHeartBeatRspLegth (pRsp)) + { + return -1; + } + *pBufLen = GetStHeartBeatRspLegth (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_INT (buf, pRsp->pid); + ENCODE_INT (buf, pRsp->uiCount); + ENCODE_CSTR_MEMCPY (buf, pRsp->strReserve, pRsp->cReseveLength); + return 0; +} + +int DecodeHeartBeatRsp (StHeartBeatRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetStHeartBeatRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_INT (pRsp->pid, buf, &iTmpLen); + DECODE_INT (pRsp->uiCount, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strReserve, pRsp->cReseveLength, buf, &iTmpLen); + return 0; +} + +//***************************0x02 注册,建立连接************************** +//请求 + +int GetRegisterReqBaseLegth () +{ + return sizeof (int) + 10 * sizeof (char); +} + +int GetRegisterReqLegth (const StRegisterReq * pReq) +{ + return GetRegisterReqBaseLegth () + pReq->cSolaceHostLen + + pReq->cSolaceVpnLen + pReq->cSolaceUserLen + pReq->cSolacePwdLen + + pReq->cConsumerIpLen + pReq->cConsumerSysIdLen + pReq->cConsumerDcnLen + + pReq->cConsumerOrgIdLen + pReq->cConsumerVersionLen + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeStRegisterReq (char *buf, int *pBufLen, const StRegisterReq * pReq) +{ + if (*pBufLen < GetRegisterReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetRegisterReqLegth (pReq); + ENCODE_INT (buf, pReq->iPid); + ENCODE_CSTR_MEMCPY (buf, pReq->strSolaceHost, pReq->cSolaceHostLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strSolaceVpn, pReq->cSolaceVpnLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strSolaceUser, pReq->cSolaceUserLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strSolacePwd, pReq->cSolacePwdLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerIp, pReq->cConsumerIpLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerSysId, pReq->cConsumerSysIdLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerDcn, pReq->cConsumerDcnLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerOrgId, pReq->cConsumerOrgIdLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strConsumerVersion, + pReq->cConsumerVersionLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodeStRegisterReq (StRegisterReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterReqBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->iPid, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strSolaceHost, pReq->cSolaceHostLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strSolaceVpn, pReq->cSolaceVpnLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strSolaceUser, pReq->cSolaceUserLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strSolacePwd, pReq->cSolacePwdLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerIp, pReq->cConsumerIpLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerSysId, pReq->cConsumerSysIdLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerDcn, pReq->cConsumerDcnLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerOrgId, pReq->cConsumerOrgIdLen, buf, + &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strConsumerVersion, pReq->cConsumerVersionLen, + buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +int GetRegisterRspBaseLegth () +{ + return sizeof (char) + 3 * sizeof (int); +} + +int GetRegisterRsplength (const StRegisterRsp * pRsp) +{ + return GetRegisterRspBaseLegth () + pRsp->cReseveLength; +} + +int EncodeStRegisterRsp (char *buf, int *pBufLen, const StRegisterRsp * pRsp) +{ + if (*pBufLen < GetRegisterRsplength (pRsp)) + { + return -1; + } + *pBufLen = GetRegisterRsplength (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_INT (buf, pRsp->uiCcdIndex); + ENCODE_INT (buf, pRsp->uiCcdFlow); + ENCODE_CSTR_MEMCPY (buf, pRsp->strReserve, pRsp->cReseveLength); + return 0; +} + +int DecodeStRegisterRsp (StRegisterRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_INT (pRsp->uiCcdIndex, buf, &iTmpLen); + DECODE_INT (pRsp->uiCcdFlow, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strReserve, pRsp->cReseveLength, buf, &iTmpLen); + return 0; +} + +//***********************************0x06 注册接收连接*********************************** +int GetRegisterReceiveReqBaseLegth () +{ + return 2 * sizeof (int) + sizeof (char); +} + +int GetRegisterReceiveReqLegth (const StRegisterReceiveReq * pReq) +{ + return GetRegisterReceiveReqBaseLegth () + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeStRegisterReceiveReq (char *buf, int *pBufLen, + const StRegisterReceiveReq * pReq) +{ + if (*pBufLen < GetRegisterReceiveReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetRegisterReceiveReqLegth (pReq); + ENCODE_INT (buf, pReq->uiCcdIndex); + ENCODE_INT (buf, pReq->uiCcdFlow); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodeStRegisterReceiveReq (StRegisterReceiveReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterReceiveReqBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->uiCcdIndex, buf, &iTmpLen); + DECODE_INT (pReq->uiCcdFlow, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +int GetRegisterReceiveRspBaseLegth () +{ + return sizeof (char) + sizeof (int); +} + +int GetRegisterReceiveRsplength (const StRegisterReceiveRsp * pRsp) +{ + return GetRegisterReceiveRspBaseLegth () + pRsp->cReseveLength; +} + +int EncodeStRegisterReceiveRsp (char *buf, int *pBufLen, + const StRegisterReceiveRsp * pRsp) +{ + if (*pBufLen < GetRegisterReceiveRsplength (pRsp)) + { + return -1; + } + *pBufLen = GetRegisterReceiveRsplength (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_CSTR_MEMCPY (buf, pRsp->strReserve, pRsp->cReseveLength); + return 0; +} + +int DecodeStRegisterReceiveRsp (StRegisterRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterReceiveRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strReserve, pRsp->cReseveLength, buf, &iTmpLen); + return 0; +} + +int GetAddListenReqLegth (const StAddListenReq * pReq) +{ + return sizeof (pReq->strSceneId) + sizeof (pReq->strServiceId); +} + +//return -1.空间不足 +int EncodeAddListenReq (char *buf, int *pBufLen, const StAddListenReq * pReq) +{ + if (*pBufLen < GetAddListenReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetAddListenReqLegth (pReq); + memcpy (buf, pReq->strServiceId, sizeof (pReq->strServiceId)); + buf = buf + sizeof (pReq->strServiceId); + memcpy (buf, pReq->strSceneId, sizeof (pReq->strSceneId)); + return 0; +} + +int DecodeAddListenReq (StAddListenReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetAddListenReqLegth (pReq)) + { + return -1; + } + memcpy (pReq->strServiceId, buf, sizeof (pReq->strServiceId)); + memcpy (pReq->strSceneId, buf + sizeof (pReq->strServiceId), + sizeof (pReq->strSceneId)); + return 0; +} + +int GetAddListenRspBaseLegth () +{ + return sizeof (int); +} + +int GetAddListenRspLegth (const StAddListenRsp * pRsp) +{ + return GetAddListenRspBaseLegth () + sizeof (pRsp->strSceneId) + + sizeof (pRsp->strServiceId); +} + +//return -1.空间不足 +int EncodeAddListenRsp (char *buf, int *pBufLen, const StAddListenRsp * pRsp) +{ + if (*pBufLen < GetAddListenRspLegth (pRsp)) + { + return -1; + } + *pBufLen = GetAddListenRspLegth (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + memcpy (buf, pRsp->strServiceId, sizeof (pRsp->strServiceId)); + memcpy (buf, pRsp->strSceneId, sizeof (pRsp->strSceneId)); + return 0; +} + +int DecodeAddListenRsp (StAddListenRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetAddListenRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + memcpy (pRsp->strServiceId, buf, sizeof (pRsp->strServiceId)); + memcpy (pRsp->strSceneId, buf, sizeof (pRsp->strSceneId)); + return 0; +} + +//***************************0x06 增加监听************************** +int GetAddManageBaseLength () +{ + return sizeof (char); +} + +int GetAddManageReqLegth (const StAddManageReq * pReq) +{ + return GetAddManageBaseLength () + pReq->cManageTopicLength; +} + +//return -1.空间不足 +int EncodeAddManageReq (char *buf, int *pBufLen, const StAddManageReq * pReq) +{ + if (*pBufLen < GetAddManageReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetAddManageReqLegth (pReq); + ENCODE_CSTR_MEMCPY (buf, pReq->strManageTopic, pReq->cManageTopicLength); + return 0; +} + +int DecodeAddManageReq (StAddManageReq * pReq, const char *buf, + const int bufLen) +{ + if (bufLen < GetRegisterReceiveRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_CSTR_MEMCPY (pReq->strManageTopic, pReq->cManageTopicLength, buf, + &iTmpLen); + return 0; +} + +int GetAddManageRspBaseLegth () +{ + return sizeof (int) + sizeof (char); +} + +int GetAddManageRspLegth (const StAddManageRsp * pRsp) +{ + return GetAddManageRspBaseLegth () + pRsp->cManageTopicLength; +} + +//return -1.空间不足 +int EncodeAddManageRsp (char *buf, int *pBufLen, const StAddManageRsp * pRsp) +{ + if (*pBufLen < GetAddManageRspLegth (pRsp)) + { + return -1; + } + *pBufLen = GetAddManageRspLegth (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_CSTR_MEMCPY (buf, pRsp->strManageTopic, pRsp->cManageTopicLength); + return 0; +} + +int DecodeAddManageRsp (StAddManageRsp * pRsp, const char *buf, + const int bufLen) +{ + if (bufLen < GetAddManageRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strManageTopic, pRsp->cManageTopicLength, buf, + &iTmpLen); + return 0; +} + +//***************************0x04 worker发包************************** + +int GetSendMsgReqBaseLength () +{ + return 3 * sizeof (int) + sizeof (char); +} + +int GetSendMsgReqLength (const StSendMsgReq * pReq) +{ + return GetSendMsgReqBaseLength () + pReq->uiWemqMsgLen + + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeSendMsgReq (char *buf, int *pBufLen, const StSendMsgReq * pReq) +{ + if (*pBufLen < GetSendMsgReqLength (pReq)) + { + return -1; + } + *pBufLen = GetSendMsgReqLength (pReq); + ENCODE_INT (buf, pReq->uiMsgType); + ENCODE_INT (buf, pReq->uiSendMsgSeq); + ENCODE_DWSTR_MEMCPY (buf, pReq->strWemqMsg, pReq->uiWemqMsgLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodeSendMsgReq (StSendMsgReq * pReq, const char *buf, const int bufLen) +{ + if (bufLen < GetSendMsgReqBaseLength ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->uiMsgType, buf, &iTmpLen); + DECODE_INT (pReq->uiSendMsgSeq, buf, &iTmpLen); + DECODE_DWSTR_MEMCPY (pReq->strWemqMsg, pReq->uiWemqMsgLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +int GetSendMsgRspBaseLength () +{ + return 3 * sizeof (int) + sizeof (char); +} + +int GetSendMsgRspLength (const StSendMsgRsp * pRsp) +{ + return GetSendMsgRspBaseLength () + pRsp->cUuidLen; +} + +//return -1.空间不足 +int EncodeSendMsgRsp (char *buf, int *pBufLen, const StSendMsgRsp * pRsp) +{ + if (*pBufLen < GetSendMsgRspLength (pRsp)) + { + return -1; + } + *pBufLen = GetSendMsgRspLength (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_INT (buf, pRsp->uiMsgType); + ENCODE_INT (buf, pRsp->uiRecvMsgSeq); + ENCODE_CSTR_MEMCPY (buf, pRsp->strUuid, pRsp->cUuidLen); + return 0; +} + +int DecodeSendMsgRsp (StSendMsgRsp * pRsp, const char *buf, const int bufLen) +{ + if (bufLen < GetSendMsgRspBaseLength ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_INT (pRsp->uiMsgType, buf, &iTmpLen); + DECODE_INT (pRsp->uiRecvMsgSeq, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strUuid, pRsp->cUuidLen, buf, &iTmpLen); + return 0; +} + +//***************************0x05 worker发送消息ack************************** +//请求,为避免其他业务代码错误导致把其他人的msg ack掉, 因此这里将sessionId和sessionIndex flowIndex做核对 + +int GetAckMsgReqBaseLength () +{ + return 2 * sizeof (int) + 2 * sizeof (char) + sizeof (long); +} + +int GetAckMsgReqLength (const StAckMsgReq * pReq) +{ + return GetAckMsgReqBaseLength () + pReq->cUuidLen + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodeAckMsgReq (char *buf, int *pBufLen, const StAckMsgReq * pReq) +{ + if (*pBufLen < GetAckMsgReqLength (pReq)) + { + return -1; + } + *pBufLen = GetAckMsgReqLength (pReq); + ENCODE_INT (buf, pReq->uiSessionIndex); + ENCODE_INT (buf, pReq->uiFlowIndex); + ENCODE_LONG (buf, pReq->ulMsgId); + ENCODE_CSTR_MEMCPY (buf, pReq->strUuid, pReq->cUuidLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodeAckMsgReq (StAckMsgReq * pReq, const char *buf, const int bufLen) +{ + if (bufLen < GetAckMsgReqBaseLength ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pReq->uiSessionIndex, buf, &iTmpLen); + DECODE_INT (pReq->uiFlowIndex, buf, &iTmpLen); + DECODE_LONG (pReq->ulMsgId, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strUuid, pReq->cUuidLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +//回包 + +int GetAckMsgRspBaseLength () +{ + return 3 * sizeof (int) + sizeof (char) + sizeof (unsigned long); +} + +int GetAckMsgRspLength (const StAckMsgRsp * pReq) +{ + return GetAckMsgRspBaseLength () + pReq->cUuidLen; +} + +//return -1.空间不足 +int EncodeAckMsgRsp (char *buf, int *pBufLen, const StAckMsgRsp * pRsp) +{ + if (*pBufLen < GetAckMsgRspLength (pRsp)) + { + return -1; + } + *pBufLen = GetAckMsgRspLength (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_INT (buf, pRsp->uiSessionIndex); + ENCODE_INT (buf, pRsp->uiFlowIndex); + ENCODE_LONG (buf, pRsp->ulMsgId); + ENCODE_CSTR_MEMCPY (buf, pRsp->strUuid, pRsp->cUuidLen); + return 0; +} + +int DecodeAckMsgRsp (StAckMsgRsp * pRsp, const char *buf, const int bufLen) +{ + if (bufLen < GetAckMsgRspBaseLength ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_INT (pRsp->uiSessionIndex, buf, &iTmpLen); + DECODE_INT (pRsp->uiFlowIndex, buf, &iTmpLen); + DECODE_LONG (pRsp->ulMsgId, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strUuid, pRsp->cUuidLen, buf, &iTmpLen); + return 0; +} + +//以下为proxy推送消息 +//***************************0x50 proxy下发消息************************** +int GetPushMsgReqBaseLegth () +{ + return (2 * sizeof (int) + 2 * sizeof (char)); +} + +int GetPushMsgReqLegth (const StPushMsgReq * pReq) +{ + return GetPushMsgReqBaseLegth () + pReq->uiWemqMsgLen + pReq->cReseveLength; +} + +//return -1.空间不足 +int EncodePushMsgReq (char *buf, int *pBufLen, const StPushMsgReq * pReq) +{ + if (*pBufLen < GetPushMsgReqLegth (pReq)) + { + return -1; + } + *pBufLen = GetPushMsgReqLegth (pReq); + ENCODE_CHAR (buf, pReq->cWemqMsgType); + ENCODE_INT (buf, pReq->uiSeq); + ENCODE_DWSTR_MEMCPY (buf, pReq->strWemqMsg, pReq->uiWemqMsgLen); + ENCODE_CSTR_MEMCPY (buf, pReq->strReserve, pReq->cReseveLength); + return 0; +} + +int DecodePushMsgReq (StPushMsgReq * pReq, const char *buf, const int bufLen) +{ + if (bufLen < GetPushMsgReqBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_CHAR (pReq->cWemqMsgType, buf, &iTmpLen); + DECODE_INT (pReq->uiSeq, buf, &iTmpLen); + DECODE_DWSTR_MEMCPY (pReq->strWemqMsg, pReq->uiWemqMsgLen, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pReq->strReserve, pReq->cReseveLength, buf, &iTmpLen); + return 0; +} + +//回包 + +int GetPushMsgRspBaseLegth () +{ + return sizeof (int) + sizeof (char); +} + +int GetPushMsgRspLegth (const StPushMsgRsp * pRsp) +{ + return GetPushMsgRspBaseLegth () + pRsp->cUuidLen; +} + +//return -1.空间不足 +int EncodePushMsgRsp (char *buf, int *pBufLen, const StPushMsgRsp * pRsp) +{ + if (*pBufLen < GetPushMsgRspLegth (pRsp)) + { + return -1; + } + *pBufLen = GetPushMsgRspLegth (pRsp); + ENCODE_INT (buf, pRsp->uiResult); + ENCODE_CSTR_MEMCPY (buf, pRsp->strUuid, pRsp->cUuidLen); + return 0; +} + +int DecodePushMsgRsp (StPushMsgRsp * pRsp, const char *buf, const int bufLen) +{ + if (bufLen < GetPushMsgRspBaseLegth ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pRsp->uiResult, buf, &iTmpLen); + DECODE_CSTR_MEMCPY (pRsp->strUuid, pRsp->cUuidLen, buf, &iTmpLen); + return 0; +} + +//*************************************************wemq worker-proxy包格式***************************** +//msg的组成都是header + msgbuf, 其中header的头4个字节为长度 +int GetWemqHeaderLen () +{ + return 5 * sizeof (int) + sizeof (unsigned short); +} + +int EncodeWemqHeader (char *buf, int *pBufLen, const StWemqHeader * pHeader) +{ + if (*pBufLen < GetWemqHeaderLen ()) + { + return -1; + } + *pBufLen = GetWemqHeaderLen (); + + ENCODE_INT (buf, pHeader->uiPkgLen); + ENCODE_INT (buf, 0xFFFFFFFF); + ENCODE_SHORT (buf, pHeader->usCmd); + ENCODE_INT (buf, pHeader->uiSessionId); + ENCODE_INT (buf, pHeader->uiSeq); + ENCODE_INT (buf, pHeader->uiReserved); + return 0; +} + +int DecodeWemqHeader (StWemqHeader * pHeader, const char *buf, + const int bufLen) +{ + if (bufLen < GetWemqHeaderLen ()) + { + return -1; + } + int iTmpLen = bufLen; + DECODE_INT (pHeader->uiPkgLen, buf, &iTmpLen); + DECODE_INT (pHeader->uiColorFlag, buf, &iTmpLen); + DECODE_SHORT (pHeader->usCmd, buf, &iTmpLen); + DECODE_INT (pHeader->uiSessionId, buf, &iTmpLen); + DECODE_INT (pHeader->uiSeq, buf, &iTmpLen); + DECODE_INT (pHeader->uiReserved, buf, &iTmpLen); + return 0; +} + +int DecodeWeMQMsg (StWeMQMSG * pMsg, const char *buf, const int bufLen) +{ + int iTmpLen = bufLen; + DECODE_INT (pMsg->uiTotalLen, buf, &iTmpLen); + DECODE_INT (pMsg->uiHeaderLen, buf, &iTmpLen); +/* + DECODE_DWSTR_MEMCPY(pMsg->cStrJsonHeader,pMsg->uiHeaderLen,buf,&iTmpLen); + pMsg->cStrJsonHeader[pMsg->uiHeaderLen] = '\0'; + DECODE_DWSTR_MEMCPY(pMsg->cStrJsonBody, pMsg->uiTotalLen - pMsg->uiHeaderLen - 8, buf, &iTmpLen); + pMsg->cStrJsonHeader[pMsg->uiTotalLen - pMsg->uiHeaderLen - 8] = '\0'; +*/ + return 0; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_tcp.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_tcp.c new file mode 100644 index 0000000000..971fec4c1e --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_tcp.c @@ -0,0 +1,773 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "wemq_tcp.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rmb_define.h" + +// return=0: timeout; return<0: error; return>0: success. +static int check_recv (int fd, int iSec, int iMs) +{ + fd_set rset; + int ret; + + FD_ZERO (&rset); + FD_SET (fd, &rset); + + struct timeval tv; + tv.tv_sec = iSec; + tv.tv_usec = iMs * 1000; + + do + { + ret = select (fd + 1, &rset, NULL, NULL, &tv); + } + while (ret < 0 && errno == EINTR); + + // 如果rset只有一个socket, 不需要去判断FD_ISSET + if (ret > 0 && FD_ISSET (fd, &rset)) + { + return 1; + } + + return (ret == 0 ? 0 : -1); +} + +// return=0: timeout; return<0: error; return>0: success. +static int check_send (int fd, int iSec, int iMs) +{ + fd_set wset; + int ret; + + FD_ZERO (&wset); + FD_SET (fd, &wset); + + struct timeval tv; + tv.tv_sec = iSec; + tv.tv_usec = iMs * 1000; + + do + { + ret = select (fd + 1, NULL, &wset, NULL, &tv); + } + while (ret < 0 && errno == EINTR); + + // 如果rset只有一个socket, 不需要去判断FD_ISSET + if (ret > 0 && FD_ISSET (fd, &wset)) + { + return 1; + } + + return (ret == 0 ? 0 : -1); +} + +//************************************ +// Method: wemq_tcp_connect +// FullName: wemq_tcp_connect +// Access: public +// Returns: int if connect success return socket fd, else return -1 +// Qualifier: +// Parameter: const char * ip +// Parameter: uint16_t port +// Parameter: int timeout:单位为ms +//************************************ +int wemq_tcp_connect (const char *ip, uint16_t port, int timeout) +{ + int sockfd = -1; + struct sockaddr_in servaddr; + int flag = 0; + int ret = 0; + + if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0) + { + return -1; + } + if (timeout > 0) + { + flag = fcntl (sockfd, F_GETFL) | O_NONBLOCK; + fcntl (sockfd, F_SETFL, flag); + } + + bzero (&servaddr, sizeof (servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons (port); + if (inet_pton (AF_INET, ip, &servaddr.sin_addr) <= 0) + { + close (sockfd); + return -2; + } + + do + { + ret = + connect (sockfd, (struct sockaddr *) &servaddr, + sizeof (struct sockaddr_in)); + } + while (ret < 0 && errno == EINTR); + if ((ret != 0) && (errno != EWOULDBLOCK) && (errno != EINPROGRESS)) + { + close (sockfd); + return -3; + } + + // 判断是否需要超时 + if (timeout > 0) + { + fd_set write_set; + struct timeval tv; + int sock_err = 0; + int sock_err_len = sizeof (sock_err); + + FD_ZERO (&write_set); + FD_SET (sockfd, &write_set); + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + do + { + ret = select (FD_SETSIZE, NULL, &write_set, NULL, &tv); + } + while (ret < 0 && errno == EINTR); + if (ret <= 0 || !FD_ISSET (sockfd, &write_set)) + { + close (sockfd); + return 0; + } + + //getscokopt: check socket connect + if (getsockopt + (sockfd, SOL_SOCKET, SO_ERROR, (char *) &sock_err, + (socklen_t *) & sock_err_len) != 0) + { + close (sockfd); + return -4; + } + if (sock_err != 0) + { + close (sockfd); + return -5; + } + + //block + flag &= ~O_NONBLOCK; + fcntl (sockfd, F_SETFL, flag); + } + return sockfd; +} + +//************************************ +// Method: wemq_tcp_send +// FullName: wemq_tcp_send +// Access: public +// Returns: int 0 for success, -1 for error +// Qualifier: +// Parameter: int fd connected socket +// Parameter: char * msg message buffer +// Parameter: uint32_t len message length +//************************************ +int wemq_tcp_send (int fd, void *msg, uint32_t totalLen, uint32_t headerLen, + int iTimeOut, SSL * ssl) +{ + //uint32_t uiHeadRemain = 4; + //uint32_t uiHeadSend = 0; + if (fd < 0 || msg == NULL) + { + return -1; + } + if (iTimeOut <= 0) + { + iTimeOut = 1000; + } + /* + while (uiHeadRemain > 0) + { + iRet = check_send(fd, iTimeOut/1000, iTimeOut%1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB(RMB_LOG_ERROR, "check_send error, errno=%d\n", errno); + return -2; + } + iRet = send(fd, "JSON", uiHeadRemain, 0); + if (iRet < 0) + { + LOGRMB(RMB_LOG_ERROR, "send error, errno=%d\n", errno); + return -2; + } + uiHeadSend += iRet; + uiHeadRemain -= iRet; + } + */ + int iRet; + uint32_t uiRemain = totalLen + 8; + uint32_t uiSend = 0; + char *msg_temp = (char *) malloc ((totalLen + 8) * sizeof (char)); + char *msg_new = msg_temp; + ENCODE_DWSTR_MEMCPY (msg_temp, "WEMQ", 4); + ENCODE_DWSTR_MEMCPY (msg_temp, "0000", 4); + ENCODE_DWSTR_MEMCPY (msg_temp, msg, totalLen); + // LOGRMB(RMB_LOG_DEBUG, "tcp data=%s\n", msg_temp); + //LOGRMB(RMB_LOG_DEBUG, "tcp data2=%s\n", (char *)msg); + while (uiRemain > 0) + { + iRet = check_send (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_send error, errno=%d\n", errno); + return -2; + } + if (NULL != ssl) + { + iRet = SSL_write (ssl, msg_new + uiSend, uiRemain); + } + else + { + iRet = send (fd, msg_new + uiSend, uiRemain, 0); + } + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "send error, errno=%d, iRet=%d\n", errno, iRet); + return -2; + } + uiSend += iRet; + uiRemain -= iRet; + } + free (msg_new); + return uiSend; +} + +int wemq_ssl_recv (int fd, void *msg, uint32_t * len, int iTimeOut, SSL * ssl) +{ + int iRet; + uint32_t uiRemain, uiRecved; + + uiRemain = 4; + uiRecved = 0; + if (fd < 0 || msg == NULL || len == NULL) + { + return -1; + } + if (iTimeOut <= 0) + { + iTimeOut = 1000; + } + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != 4 || strcmp (msg, "WEMQ") != 0) + { + LOGRMB (RMB_LOG_ERROR, "recv msg header error,%u:%s", uiRecved, + (char *) msg); + return -3; + } + + uiRemain = 4; + uiRecved = 0; + while (uiRemain > 0) + { + int iRecv = 0; + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + if (iRecv > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + if (0 == uiRemain) + { + break; + } + + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + if (NULL != ssl) + { + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + } + else + { + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + } + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + //LOGRMB(RMB_LOG_DEBUG, "Recv version = %s\n", (char *)msg); + if (uiRecved != 4) + { + LOGRMB (RMB_LOG_ERROR, "recv msg version error,%u:%s", uiRecved, + (char *) msg); + return -3; + } + + // read msg length + uiRemain = 4; + uiRecved = 0; + while (uiRemain > 0) + { + int iRecv = 0; + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + if (iRecv > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + if (0 == uiRemain) + { + break; + } + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + + if (NULL != ssl) + { + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + } + else + { + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + } + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != 4) + { + // can't read 4 bytes + LOGRMB (RMB_LOG_ERROR, "recv less than 4, recv %d bytes\n", uiRecved); + return -3; + } + + *len = ntohl (*(uint32_t *) msg); + + uiRemain = *len - 4; + while (uiRemain > 0) + { + int iRecv = 0; + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + if (iRecv > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + if (0 == uiRemain) + { + break; + } + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + + if (NULL != ssl) + { + iRecv = SSL_read (ssl, msg + uiRecved, uiRemain); + } + else + { + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + } + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != *len) + { + // can't recv whole msg + return -3; + } + + return uiRecved; +} + +//************************************ +// Method: wemq_tcp_recv +// FullName: wemq_tcp_recv +// Access: public +// Returns: int 0 for success, -1 for error +// Qualifier: +// Parameter: int fd connected socket +// Parameter: void * msg receive message buffer +// Parameter: uint32_t * len receive message length +//************************************ +int wemq_tcp_recv (int fd, void *msg, uint32_t * len, int iTimeOut, SSL * ssl) +{ + int iRet; + uint32_t uiRemain, uiRecved; + + if (NULL != ssl) + { + return wemq_ssl_recv (fd, msg, len, iTimeOut, ssl); + } + + uiRemain = 4; + uiRecved = 0; + if (fd < 0 || msg == NULL || len == NULL) + { + return -1; + } + if (iTimeOut <= 0) + { + iTimeOut = 1000; + } + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != 4 || strcmp (msg, "WEMQ") != 0) + { + LOGRMB (RMB_LOG_ERROR, "recv msg header error,%u:%s", uiRecved, + (char *) msg); + return -3; + } + + uiRemain = 4; + uiRecved = 0; + if (fd < 0 || msg == NULL || len == NULL) + { + return -1; + } + if (iTimeOut <= 0) + { + iTimeOut = 1000; + } + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + //LOGRMB(RMB_LOG_DEBUG, "Recv version = %s\n", (char *)msg); + if (uiRecved != 4) + { + LOGRMB (RMB_LOG_ERROR, "recv msg version error,%u:%s", uiRecved, + (char *) msg); + return -3; + } + + // read msg length + uiRemain = 4; + uiRecved = 0; + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != 4) + { + // can't read 4 bytes + LOGRMB (RMB_LOG_ERROR, "recv less than 4, recv %d bytes\n", uiRecved); + return -3; + } + + *len = ntohl (*(uint32_t *) msg); + + uiRemain = *len - 4; + while (uiRemain > 0) + { + int iRecv = 0; + iRet = check_recv (fd, iTimeOut / 1000, iTimeOut % 1000); + if (iRet == 0) + { + return 0; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "check_recv error, error=%d\n", errno); + return -2; + } + + iRecv = recv (fd, msg + uiRecved, uiRemain, 0); + if (iRecv < 0 && (errno != EAGAIN)) + { + LOGRMB (RMB_LOG_ERROR, "Recv error, fd close() error=%d, iRecv=%d\n", + errno, iRecv); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, "Peer close connect, fd close() errno=%d\n", + errno); + return -2; + } + if (iRet > 0) + { + uiRecved += iRecv; + uiRemain -= iRecv; + } + } + + if (uiRecved != *len) + { + // can't recv whole msg + return -3; + } + + return uiRecved; +} + +int wemq_tcp_close (int fd, SSL * ssl) +{ + if (NULL != ssl) + { + SSL_shutdown (ssl); + SSL_free (ssl); + } + if (fd >= 0) + { + close (fd); + } + + return 0; +} + +// 获取当前socket本地的IP和端口 +void wemq_getsockename (int fd, char *ip, uint32_t len, int *port) +{ + struct sockaddr_in guest; + socklen_t guest_len = sizeof (guest); + + if (fd <= 0 || port == NULL) + { + return; + } + if (getsockname (fd, (struct sockaddr *) &guest, (socklen_t *) & guest_len) + != 0) + { + return; + } + *port = ntohs (guest.sin_port); + if (ip != NULL && len > 0) + { + inet_ntop (AF_INET, &guest.sin_addr, ip, len); + } +} + +// 获取当前socket远端的IP和端口 +void wemq_getpeername (int fd, char *ip, uint32_t len, int *port) +{ + struct sockaddr_in svr; + socklen_t svr_len = sizeof (svr); + + if (fd <= 0 || port == NULL) + { + return; + } + if (getpeername (fd, (struct sockaddr *) &svr, (socklen_t *) & svr_len) != + 0) + { + return; + } + *port = ntohs (svr.sin_port); + if (ip != NULL && len > 0) + { + inet_ntop (AF_INET, &svr.sin_addr, ip, len); + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_thread.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_thread.c new file mode 100644 index 0000000000..7ca2c9c638 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_thread.c @@ -0,0 +1,5467 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include "common.h" +#include "wemq_thread.h" +#include "rmb_common.h" +#include "rmb_errno.h" +#include "wemq_tcp.h" +#include "rmb_pub.h" +#include "rmb_sub.h" +#include "rmb_access_config.h" +#define MAX_EVENTS 100 +#define HEART_BEAT_COUNT 300 +#define HEART_BEAT_PERIOD 15 +#define CHECK_RR_EMPTY_PERIOD 10 + +static enum _wemq_message_ret +{ + WEMQ_MESSAGE_RET_ERR = -1, + WEMQ_MESSAGE_RET_GOODBYE = 88, + WEMQ_MESSAGE_RET_CLIENTGOODBYE = 881, + WEMQ_MESSAGE_RET_SERVERGOODBYE = 882, + WEMQ_MESSAGE_RET_REDIRECT = 300, +}; + +extern const char *vecManageTopic[10]; +unsigned long long ullNow = 0; +char *STATE_MAP[10] = { + "THREAD_STATE_INIT", + "THREAD_STATE_CONNECT", + "THREAD_STATE_REGI", + "THREAD_STATE_OK", + "THREAD_STATE_CLOSE", + "THREAD_STATE_SERVER_BREAK", + "THREAD_STATE_BREAK", + "THREAD_STATE_RECONNECT", + "THREAD_STATE_DESTORY", + "THREAD_STATE_EXIT" +}; + +char *_wemq_cmd_map[] = { + "", + "CMD_BEAT", + "CMD_REGI", + "CMD_ADD_LISTEN", + "CMD_SEND_MSG", + "CMD_SEND_MSG_ACK", + "CMD_ADD_MANAGE", + "CMD_SEND_REQUEST", + "CMD_SEND_REQUEST_ASYNC", + "CMD_SEND_REPLY", + "CMD_SEND_PUSH", + "CMD_SEND_START" +}; + +static int32_t _wemq_thread_do_send_sync (WemqThreadCtx * pThreadCtx, + void *msg, uint32_t totalLen, + uint32_t headerLen); + +/* +unsigned long long _wemq_thread_get_cur_time() +{ + struct timeval _curTimeVal; + gettimeofday(&_curTimeVal, NULL); + ullNow = (unsigned long)_curTimeVal.tv_sec * (unsigned long)1000UL + (unsigned long)_curTimeVal.tv_usec / 1000UL; + return ullNow; +} +*/ + +static int _wemq_get_executable_path (char *processdir, size_t len) +{ + char *path_end; + if (readlink ("/proc/self/exe", processdir, len) <= 0) + return -1; + path_end = strrchr (processdir, '/'); + if (path_end == NULL) + return -1; + return (int) (path_end - processdir); +} + +static const char *_wemq_thread_get_cmd (unsigned int usCmd) +{ + const char *pRet = NULL; +// if (usCmd <= 0x50) +// { +// pRet = _wemq_cmd_map[usCmd]; +// } +// else +// { +// pRet = "CMD_PUSH"; +// } + + switch (usCmd) + { + case THREAD_MSG_CMD_BEAT: + case THREAD_MSG_CMD_REGI: + case THREAD_MSG_CMD_ADD_LISTEN: + case THREAD_MSG_CMD_SEND_MSG: + case THREAD_MSG_CMD_SEND_MSG_ACK: + case THREAD_MSG_CMD_ADD_MANAGE: + case THREAD_MSG_CMD_SEND_REQUEST: + case THREAD_MSG_CMD_SEND_REQUEST_ASYNC: + case THREAD_MSG_CMD_SEND_REPLY: + case THREAD_MSG_CMD_START: + pRet = _wemq_cmd_map[usCmd]; + break; + + case THREAD_MSG_CMD_SEND_PUSH: + pRet = "CMD_PUSH"; + break; + + default: + pRet = "CMD_ERROR"; + } + + return pRet; +} + +static int32_t _wemq_thread_check_init (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_connect (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_regi (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_ok (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_close (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_reconnect (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_break (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +static int32_t _wemq_thread_check_destory (WemqThreadCtx * pThreadCtx) +{ + return 0; +} + +/** + * 心跳包: + * cmd:HEARTBEAT_REQUEST + * headerJson={"code":0,"seq":"0160616463","command":"HEARTBEAT_REQUEST"}|bodyJson=null + * + */ +static int32_t _wemq_thread_make_heart_beat_pkg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pThreadMsg = &pThreadCtx->m_stHeartBeat; + memset (pThreadMsg, 0, sizeof (StWemqThreadMsg)); + pThreadMsg->m_iCmd = THREAD_MSG_CMD_BEAT; + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (HEARTBEAT_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + pThreadMsg->m_iHeaderLen = strlen (header_str); + + pThreadMsg->m_pHeader = + (char *) malloc (pThreadMsg->m_iHeaderLen * sizeof (char) + 1); + if (pThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for heart beat header failed"); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pHeader, header_str, pThreadMsg->m_iHeaderLen); + pThreadMsg->m_pHeader[pThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + pThreadMsg->m_iBodyLen = 0; + pThreadMsg->m_pBody = NULL; + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] make heart beat pkg succ %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadMsg->m_pHeader); + return 0; +} + +/** + * 发送start listen命令: + * cmd:LISTEN_REQUEST + * headerJson={"code":0,"seq":"7542688344","command":"LISTEN_REQUEST"}|bodyJson=null + * + */ +static int32_t _wemq_thread_make_start_listen_pkg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pThreadMsg = &pThreadCtx->m_stListen; + memset (pThreadMsg, 0, sizeof (StWemqThreadMsg)); + pThreadMsg->m_iCmd = THREAD_MSG_CMD_START; + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (LISTEN_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + pThreadMsg->m_iHeaderLen = strlen (header_str); + + pThreadMsg->m_pHeader = + (char *) malloc (pThreadMsg->m_iHeaderLen * sizeof (char) + 1); + if (pThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for listen header failed"); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pHeader, header_str, pThreadMsg->m_iHeaderLen); + pThreadMsg->m_pHeader[pThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + pThreadMsg->m_iBodyLen = 0; + pThreadMsg->m_pBody = NULL; + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] make listen pkg succ %s", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadMsg->m_pHeader); + return 0; +} + +/** + * 发送SUBSCRIBE_REQUEST: + * cmd:SUBSCRIBE_REQUEST + * headerJson={"code":0,"seq":"1333580037","command":"SUBSCRIBE_REQUEST"}| + * bodyJson={"topicList":["PRX-e-10030002-05-3","PRX-e-10020002-02-2","PRX-s-10000002-01-0","PRX-e-10020002-06-2"]} + * + */ +static int32_t _wemq_thread_make_subscribe_pkg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pThreadMsg = &pThreadCtx->m_stListen; + memset (pThreadMsg, 0, sizeof (StWemqThreadMsg)); + pThreadMsg->m_iCmd = THREAD_MSG_CMD_ADD_LISTEN; + WEMQJSON *jsonHeader = json_object_new_object (); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (LISTEN_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + pThreadMsg->m_iHeaderLen = strlen (header_str); + + pThreadMsg->m_pHeader = + (char *) malloc (pThreadMsg->m_iHeaderLen * sizeof (char) + 1); + if (pThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for listen header failed"); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pHeader, header_str, pThreadMsg->m_iHeaderLen); + pThreadMsg->m_pHeader[pThreadMsg->m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + pThreadMsg->m_iBodyLen = 0; + pThreadMsg->m_pBody = NULL; + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] make listen pkg succ %s", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadMsg->m_pHeader); + return 0; +} + +/** + * register package: + * cmd:THREAD_STATE_REGI + * headerJson={"code":0,"seq":"5160263626","command":"HELLO_REQUEST"} + * bodyJson={"subsystem":"5023","dcn":"AC0","path":"/data/app/umg_proxy","pid":32893,"host":"127.0.0.1", +* "port":8362,"version":"2.0.11","username":"PU4283","password":"dsaiubd"} + */ +static int32_t _wemq_thread_make_hello_pkg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pThreadMsg = &pThreadCtx->m_stHelloWord; + memset (pThreadMsg, 0, sizeof (StWemqThreadMsg)); + pThreadMsg->m_iCmd = THREAD_STATE_REGI; + WEMQJSON *jsonHeader = json_object_new_object (); + + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (HELLO_REQUEST)); + + WEMQJSON *jsonBody = json_object_new_object (); + + json_object_object_add (jsonBody, "subsystem", + json_object_new_string (pRmbStConfig-> + cConsumerSysId)); + json_object_object_add (jsonBody, "dcn", + json_object_new_string (pRmbStConfig-> + cConsumerDcn)); + json_object_object_add (jsonBody, "host", + json_object_new_string (pRmbStConfig->cHostIp)); + json_object_object_add (jsonBody, "port", json_object_new_string ("")); + json_object_object_add (jsonBody, "version", + json_object_new_string (RMBVERSION)); + json_object_object_add (jsonBody, "username", + json_object_new_string (pRmbStConfig->cWemqUser)); + json_object_object_add (jsonBody, "password", + json_object_new_string (pRmbStConfig->cWemqPasswd)); + json_object_object_add (jsonBody, "idc", + json_object_new_string (pRmbStConfig->cRegion)); + json_object_object_add (jsonBody, "orgid", + json_object_new_string (pRmbStConfig->strOrgId)); + + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + json_object_object_add (jsonBody, "purpose", + json_object_new_string ("pub")); + else + json_object_object_add (jsonBody, "purpose", + json_object_new_string ("sub")); + + char processPath[1024]; + memset (processPath, 0x00, sizeof (processPath)); + _wemq_get_executable_path (processPath, 1024); + json_object_object_add (jsonBody, "path", + json_object_new_string (processPath)); + char pthread_id[32]; + snprintf (pthread_id, sizeof (pthread_id), "%u", pRmbStConfig->uiPid); + json_object_object_add (jsonBody, "pid", + json_object_new_string (pthread_id)); + + const char *header_str = json_object_get_string (jsonHeader); + const char *body_str = json_object_get_string (jsonBody); + + if (header_str == NULL) + { + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + if (body_str == NULL) + { + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + + pThreadMsg->m_iHeaderLen = strlen (header_str); + + pThreadMsg->m_pHeader = + (char *) malloc (pThreadMsg->m_iHeaderLen * sizeof (char) + 1); + if (pThreadMsg->m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello header failed"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pHeader, header_str, pThreadMsg->m_iHeaderLen); + pThreadMsg->m_pHeader[pThreadMsg->m_iHeaderLen] = '\0'; + + pThreadMsg->m_iBodyLen = strlen (body_str); + pThreadMsg->m_pBody = + (char *) malloc (pThreadMsg->m_iBodyLen * sizeof (char) + 1); + if (pThreadMsg->m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + memcpy (pThreadMsg->m_pBody, body_str, pThreadMsg->m_iBodyLen); + pThreadMsg->m_pBody[pThreadMsg->m_iBodyLen] = '\0'; + + json_object_put (jsonBody); + json_object_put (jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] make hello pkg succ, header = %s, body = %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadMsg->m_pHeader, pThreadMsg->m_pBody); + return 0; +} + +static inline int32_t _wemq_thread_state_trans (WemqThreadCtx * pThreadCtx, + int iState, int iNextState) +{ + ASSERT (pThreadCtx); + + LOGRMB (RMB_LOG_INFO, "[%s] [Type:%d] [TID:%lu] Thread State Trans to [%s]", + STATE_MAP[iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, STATE_MAP[iNextState]); + + pThreadCtx->m_iState = iNextState; + pThreadCtx->m_iLastState = iState; + return 0; +} + +static int32_t _wemq_thread_set_fd_nonblock (WemqThreadCtx * pThreadCtx, + int fd) +{ + int opts; + opts = fcntl (fd, F_GETFL); + if (opts < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] set non block error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + + opts = opts | O_NONBLOCK; + + if (fcntl (fd, F_SETFL, opts) < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] set non block error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + return 0; +} + +static int32_t _wemq_thread_add_fd (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + pThreadCtx->m_stEv.events = EPOLLIN; + pThreadCtx->m_stEv.data.fd = pThreadCtx->m_iSockFd; + + LOGRMB (RMB_LOG_INFO, "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] fd:%d\n", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, pThreadCtx->m_iSockFd); + + int iRet = -1; + iRet = + epoll_ctl (pThreadCtx->m_iEpollFd, EPOLL_CTL_ADD, pThreadCtx->m_iSockFd, + &pThreadCtx->m_stEv); + if (iRet == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] epoll ctl add error:%d\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + + return 0; +} + +static int32_t _wemq_thread_del_fd (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + int iRet = -1; + iRet = + epoll_ctl (pThreadCtx->m_iEpollFd, EPOLL_CTL_DEL, pThreadCtx->m_iSockFd, + &pThreadCtx->m_stEv); + if (iRet == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] epoll ctl del error: %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + + return 0; +} + +static int32_t _wemq_thread_del_old_fd (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + int iRet = -1; + iRet = + epoll_ctl (pThreadCtx->m_iEpollFd, EPOLL_CTL_DEL, + pThreadCtx->m_iSockFdOld, &pThreadCtx->m_stEv); + if (iRet == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] epoll ctl del error: %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, errno); + return -1; + } + + return 0; +} + +static int32_t _wemq_thread_reset_sockFd (WemqThreadCtx * pThreadCtx, + bool isRecvNewConnect) +{ + if (isRecvNewConnect) + { + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + pThreadCtx->m_iSockFdNew = -1; + pThreadCtx->sslNew = NULL; + + } + else + { + _wemq_thread_del_old_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFdOld, pThreadCtx->sslOld); + pThreadCtx->m_iSockFdOld = -1; + pThreadCtx->sslOld = NULL; + pThreadCtx->m_iSockFd = pThreadCtx->m_iSockFdNew; + pThreadCtx->ssl = pThreadCtx->sslNew; + } + + return 0; +} + +static inline void _wemq_thread_clear_thread_msg (StWemqThreadMsg * + pStWemqThreadMsg) +{ + if (NULL != pStWemqThreadMsg->m_pHeader) + { + free (pStWemqThreadMsg->m_pHeader); + pStWemqThreadMsg->m_pHeader = NULL; + } + if (NULL != pStWemqThreadMsg->m_pBody) + { + free (pStWemqThreadMsg->m_pBody); + pStWemqThreadMsg->m_pBody = NULL; + } + pStWemqThreadMsg->m_iCmd = 0; + pStWemqThreadMsg->m_iHeaderLen = 0; + pStWemqThreadMsg->m_iBodyLen = 0; +} + +static int32_t _wemq_thread_get_data_from_fifo (WemqThreadCtx * pThreadCtx) +{ + int32_t iRet = -1; + + if ((iRet = wemq_kfifo_is_empty (pThreadCtx->m_ptFifo))) + { + return 0; + } + if ((iRet = + wemq_kfifo_get (pThreadCtx->m_ptFifo, + &pThreadCtx->m_stWemqThreadMsg)) < 1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] wemq_fifo is not empty, but get 0 bytes\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + return -1; + } + + ASSERT (iRet == 1); + pThreadCtx->m_iWemqThreadMsgHandled = 0; + return iRet; +} + +static int32_t _wemq_thread_dyed_msg_ack_to_access (WemqThreadCtx * + pThreadCtx, int seq, + int status, char *msgType, + StRmbMsg * ptSendMsg) +{ + char *buf = pThreadCtx->m_pSendBuff; + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (msgType)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (seq)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (status)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + return -1; + } + int wemqMsgType = 0; + if (strcmp (msgType, REQUEST_TO_CLIENT) == 0 + || strcmp (msgType, ASYNC_MESSAGE_TO_CLIENT) + || strcmp (msgType, BROADCAST_MESSAGE_TO_CLIENT)) + { + wemqMsgType = THREAD_MSG_CMD_SEND_MSG_ACK; + } + else if (strcmp (msgType, RESPONSE_TO_CLIENT)) + { + wemqMsgType = THREAD_MSG_CMD_RECV_MSG_ACK; + } + + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonBody, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (wemqMsgType, ptSendMsg); + if (jsonBodyProperty == NULL) + { + json_object_put (jsonHeader); + json_object_put (jsonBody); + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_PROPERTY_JSON, jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (wemqMsgType, ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonBody, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return -1; + } + + int iHeaderLen = strlen (header_str); + int iBodyLen = strlen (body_str); + int iTotalLen = iHeaderLen + iBodyLen + 8; + + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, header_str, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, body_str, iBodyLen); +// json_object_put(jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send:header_str:%s body_str:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, header_str, + body_str); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + iHeaderLen); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_resp_ack_to_access error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_dyed_msg_reply_to_access (WemqThreadCtx * + pThreadCtx, int seq, + int status, + char *msgType, + StRmbMsg * ptSendMsg) +{ + char *buf = pThreadCtx->m_pSendBuff; + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (msgType)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (seq)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (status)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonBody, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (THREAD_MSG_CMD_SEND_REPLY, ptSendMsg); + if (jsonBodyProperty == NULL) + { + json_object_put (jsonHeader); + json_object_put (jsonBody); + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_PROPERTY_JSON, jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (THREAD_MSG_CMD_SEND_REPLY, ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonBody, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return -1; + } + + int iHeaderLen = strlen (header_str); + int iBodyLen = strlen (body_str); + int iTotalLen = iHeaderLen + iBodyLen + 8; + + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, header_str, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, body_str, iBodyLen); +// json_object_put(jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send:header_str:%s body_str:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, header_str, + body_str); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + iHeaderLen); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_resp_ack_to_access error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_resp_ack_to_access (WemqThreadCtx * pThreadCtx, + int seq, int status, + char *msgType, + StRmbMsg * ptSendMsg) +{ + char *buf = pThreadCtx->m_pSendBuff; + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (msgType)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (seq)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (status)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonBody, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (THREAD_MSG_CMD_RECV_MSG_ACK, ptSendMsg); + if (jsonBodyProperty == NULL) + { + json_object_put (jsonHeader); + json_object_put (jsonBody); + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_PROPERTY_JSON, jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (THREAD_MSG_CMD_RECV_MSG_ACK, + ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonBody, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + + return -1; + } + + int iHeaderLen = strlen (header_str); + int iBodyLen = strlen (body_str); + int iTotalLen = iHeaderLen + iBodyLen + 8; + + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, header_str, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, body_str, iBodyLen); +// json_object_put(jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send:header_str:%s body_str:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, header_str, + body_str); + json_object_put (jsonHeader); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + iHeaderLen); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_resp_ack_to_access error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_send_error_log (WemqThreadCtx * pThreadCtx, + int seq, int errCode, + char *logPoint, char *errMsg, + StRmbMsg * ptSendMsg) +{ + char *buf = pThreadCtx->m_pSendBuff; + int iRet = -1; + WEMQJSON *jsonHeader = json_object_new_object (); + + // 组装消息 + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (TRACE_LOG_TO_LOGSERVER)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (seq)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (errCode)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + json_object_put (jsonHeader); + return -1; + } + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + json_object_put (jsonHeader); + return -1; + } + WEMQJSON *jsonMessage = json_object_new_object (); + if (jsonMessage == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object return null"); + json_object_put (jsonHeader); + json_object_put (jsonBody); + return -1; + } + char cTopic[128]; + char serviceOrEvent = (*(ptSendMsg->strServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + ptSendMsg->strTargetDcn, serviceOrEvent, ptSendMsg->strServiceId, + ptSendMsg->strScenarioId, *(ptSendMsg->strServiceId + 3)); + json_object_object_add (jsonMessage, MSG_BODY_TOPIC_STR, + json_object_new_string (cTopic)); + + WEMQJSON *jsonBodyProperty = + rmb_pub_encode_property_for_wemq (THREAD_MSG_CMD_RECV_MSG_ACK, ptSendMsg); + if (jsonBodyProperty == NULL) + { + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonBody); + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_property_for_wemq return null"); + return -1; + } + + json_object_object_add (jsonMessage, MSG_BODY_PROPERTY_JSON, + jsonBodyProperty); + + WEMQJSON *jsonByteBody = + rmb_pub_encode_byte_body_for_wemq (THREAD_MSG_CMD_RECV_MSG_ACK, + ptSendMsg); + if (jsonByteBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmb_pub_encode_byte_body_for_wemq return null"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonBody); + return -1; + } + const char *byteBodyStr = json_object_get_string (jsonByteBody); + + json_object_object_add (jsonMessage, MSG_BODY_BYTE_BODY_JSON, + json_object_new_string (byteBodyStr)); + + const char *message_str = json_object_get_string (jsonMessage); + if (message_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + return -1; + } + + json_object_object_add (jsonBody, "retCode", json_object_new_int (errCode)); + json_object_object_add (jsonBody, "retMsg", + json_object_new_string (errMsg)); + json_object_object_add (jsonBody, "level", + json_object_new_string ("error")); + json_object_object_add (jsonBody, "logPoint", + json_object_new_string (logPoint)); + json_object_object_add (jsonBody, "model", + json_object_new_string ("model")); + json_object_object_add (jsonBody, "lang", json_object_new_string ("c")); + json_object_object_add (jsonBody, "message", + json_object_new_string (message_str)); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "Get thread msg body failed\n"); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + return -1; + } + + int iHeaderLen = strlen (header_str); + int iBodyLen = strlen (body_str); + int iTotalLen = iHeaderLen + iBodyLen + 8; + + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, header_str, iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, body_str, iBodyLen); +// json_object_put(jsonHeader); + + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Send:%s\n", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, body_str); + json_object_put (jsonHeader); + json_object_put (jsonMessage); + json_object_put (jsonByteBody); + json_object_put (jsonBody); + + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + iHeaderLen); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_send log error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +/** + * access to api + * headerJson={"code":0,"seq":"0160616463","command":"REDIRECT_TO_CLIENT"}|bodyJson={"ip":"10.255.34.118", "port":10000} + */ +static int32_t _wemq_thread_on_message_redirect (WemqThreadCtx * pThreadCtx, + char *jsonBody) +{ + WEMQJSON *jsonRedirect = NULL; + WEMQJSON *jsonTmp = NULL; + int ret = 0; + + pThreadCtx->m_cRedirectIP[0] = '\0'; + pThreadCtx->m_iRedirectPort = 0; + //json_object_object_get_ex(jsonHeader ,MSG_HEAD_REDIRECT_OBJ, &jsonRedirect); + jsonRedirect = json_tokener_parse (jsonBody); + if (jsonRedirect == NULL) + { + LOGRMB (RMB_LOG_ERROR, "get redirect from body failed"); + return WEMQ_MESSAGE_RET_ERR; + } + + json_object_object_get_ex (jsonRedirect, "ip", &jsonTmp); + if (jsonTmp != NULL) + { + const char *ip = json_object_get_string (jsonTmp); + if (ip != NULL) + { + snprintf (pThreadCtx->m_cRedirectIP, sizeof (pThreadCtx->m_cRedirectIP), + "%s", ip); + json_object_object_get_ex (jsonRedirect, "port", &jsonTmp); + if (jsonTmp != NULL) + { + pThreadCtx->m_iRedirectPort = json_object_get_int (jsonTmp); + if (pThreadCtx->m_iRedirectPort > 0) + { +// pThreadCtx->m_lRedirect = true; + pThreadCtx->m_lRedirect = 1; + ret = WEMQ_MESSAGE_RET_REDIRECT; + } + else + { + pThreadCtx->m_cRedirectIP[0] = '\0'; + pThreadCtx->m_iRedirectPort = 0; + } + } + else + { + pThreadCtx->m_cRedirectIP[0] = '\0'; + } + } + } + + json_object_put (jsonRedirect); + return ret; +} + +static int32_t _wemq_thread_on_message (WemqThreadCtx * pThreadCtx, + bool isRecvNewConnect) +{ + ASSERT (pThreadCtx); + + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + StWeMQMSG *pWemqHeader = &pThreadCtx->m_stWeMQMSG; + WEMQJSON *jsonHeader = NULL; + WEMQJSON *jsonTmp = NULL; + const char *usCmd; + int serRet = -1; + int bodyLen = 0; + int seq = -1; + long time = 0; + int ret = 0; + char cMsg[RMB_MAX_ERR_MSG_FROM_ACCESS]; + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] |access2wemq_thread|Recv header:%s body:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pWemqHeader->cStrJsonHeader, pWemqHeader->cStrJsonBody); + + bodyLen = pWemqHeader->uiTotalLen - pWemqHeader->uiHeaderLen - 8; + jsonHeader = json_tokener_parse (pWemqHeader->cStrJsonHeader); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] json_tokener_parse header error: %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pWemqHeader->cStrJsonHeader) return -1; + } + //get command + json_object_object_get_ex (jsonHeader, MSG_HEAD_COMMAND_STR, &jsonTmp); + if (jsonTmp != NULL) + { + usCmd = json_object_get_string (jsonTmp); + } + //get code + json_object_object_get_ex (jsonHeader, MSG_HEAD_CODE_INT, &jsonTmp); + if (jsonTmp != NULL) + { + serRet = json_object_get_int (jsonTmp); + } + //get seq + json_object_object_get_ex (jsonHeader, MSG_HEAD_SEQ_INT, &jsonTmp); + if (jsonTmp != NULL) + { + seq = json_object_get_int (jsonTmp); + } + //get time + json_object_object_get_ex (jsonHeader, MSG_HEAD_TIME_LINT, &jsonTmp); + if (jsonTmp != NULL) + { + time = (long) json_object_get_int64 (jsonTmp); + } + memset (cMsg, 0x00, sizeof (cMsg)); + json_object_object_get_ex (jsonHeader, MSG_HEAD_MSG_STR, &jsonTmp); + if (jsonTmp != NULL) + { + strncpy (cMsg, json_object_get_string (jsonTmp), sizeof (cMsg) - 1); + } + if (strcmp (cMsg, "auth exception") == 0) + { // auth failed + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Authentication error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + return -1; + } + if (serRet != RMB_CODE_SUSS) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Time:%ld] code from access !=0, cmd=%s, seq=%d, code=%d, msg=%s!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, time, usCmd, + seq, serRet, cMsg); + } + if (strcmp (usCmd, HEARTBEAT_RESPONSE) == 0) //心跳 + { + gettimeofday (&pThreadCtx->stTimeLastRecv, NULL); + pThreadCtx->m_uiHeartBeatCurrent = 0; + + } + else if (strcmp (usCmd, HELLO_RESPONSE) == 0) + { + ret = serRet; + + } + else if (strcmp (usCmd, CLIENT_GOODBYE_RESPONSE) == 0) + { + ret = WEMQ_MESSAGE_RET_CLIENTGOODBYE; + + } + else if (strcmp (usCmd, SERVER_GOODBYE_REQUEST) == 0) + { + ret = WEMQ_MESSAGE_RET_SERVERGOODBYE; + + } + else if (strcmp (usCmd, REDIRECT_TO_CLIENT) == 0) + { + ret = + _wemq_thread_on_message_redirect (pThreadCtx, + pWemqHeader->cStrJsonBody); + + } + else if (strcmp (usCmd, ASYNC_MESSAGE_TO_SERVER_ACK) == 0) //ack 单播 from access + { + if (serRet == RMB_CODE_SUSS) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] PublishAsyncMessage request success!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + LOGRMB (RMB_LOG_DEBUG, "seq for event: %d", + pContextProxy->iSeqForEvent); + pthread_mutex_lock (&pContextProxy->eventMutex); + if (seq == pContextProxy->iSeqForEvent) + { + pContextProxy->iFlagForEvent = serRet; + pthread_cond_signal (&pContextProxy->eventCond); + } + pthread_mutex_unlock (&pContextProxy->eventMutex); + } + else if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] PublishAsyncMessage request Authentication fail!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + pthread_mutex_lock (&pContextProxy->eventMutex); + pContextProxy->iFlagForEvent = serRet; + pthread_cond_signal (&pContextProxy->eventCond); + pthread_mutex_unlock (&pContextProxy->eventMutex); + + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] PublishAsyncMessage request fail!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + pthread_mutex_lock (&pContextProxy->eventMutex); + pContextProxy->iFlagForEvent = serRet; + pthread_cond_signal (&pContextProxy->eventCond); + pthread_mutex_unlock (&pContextProxy->eventMutex); + + } + if (pContextProxy->iFlagForEvent == -1) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] send event msg signal succ! iFlagForEvent=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + serRet); + + } + + } + else if (strcmp (usCmd, ASYNC_MESSAGE_TO_CLIENT) == 0) //recv event message from proxy + { + if (serRet == 0) + { + StContext *pStContext; + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pStContext = (StContext *) (pContextProxy->pubContext); + } + else + { + pStContext = (StContext *) (pContextProxy->subContext); + } + + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStContext is null"); + + } + + int iRet = 0; + if ((iRet = + trans_json_2_rmb_msg (pStContext->pReceiveWemqMsg, + pWemqHeader->cStrJsonBody, + ASYNC_MESSAGE_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "trans_json_2_rmb_msg failed", + pStContext->pReceiveWemqMsg); + return -1; + } + pStContext->pReceiveWemqMsg->iMsgMode = RMB_MSG_FROM_WEMQ; + pStContext->pReceiveWemqMsg->cPkgType = QUEUE_PKG; + + pStContext->uiWemqPkgLen = MAX_LENTH_IN_A_MSG; + + set_extfields_2_rmb_msg (pStContext->pReceiveWemqMsg, + ASYNC_MESSAGE_TO_CLIENT, seq); + + iRet = + shift_msg_2_buf (pStContext->pWemqPkg, &pStContext->uiWemqPkgLen, + pStContext->pReceiveWemqMsg); + //LOGRMB(RMB_LOG_DEBUG, "appHeaderLen:%d", pStContext->pReceiveWemqMsg->iAppHeaderLen); + + //LOGRMB(RMB_LOG_DEBUG, "uiWemqPkgLen:%d", pStContext->uiWemqPkgLen); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "shift_msg_2_buf error!iRet=%d, %d, %s/%s/%s,unique_id=%s,mode=%d,receive=%s", + iRet, pStContext->pReceiveWemqMsg->iEventOrService, + pStContext->pReceiveWemqMsg->strTargetDcn, + pStContext->pReceiveWemqMsg->strServiceId, + pStContext->pReceiveWemqMsg->strScenarioId, + pStContext->pReceiveWemqMsg->sysHeader.cUniqueId, + pStContext->pReceiveWemqMsg->iMsgMode, + rmb_msg_print (pStContext->pReceiveWemqMsg)); + + } + //染色消息直接返回 + if (check_dyed_msg (pStContext->pReceiveWemqMsg) > 0) + { + _wemq_thread_dyed_msg_ack_to_access (pThreadCtx, seq, 0, + ASYNC_MESSAGE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsg); + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", pWemqHeader->cStrJsonBody); + return serRet; + } + int iMqIndex = req_mq_index; + LOGRMB (RMB_LOG_DEBUG, "WEMQ_CMD_ASYNCEVENT_SUB:Ready to enqueue"); + + if (pRmbStConfig->iFlagForReq == (int) MSG_IPC_MQ) + { + //if (bodyLen >= pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - C_RMB_MQ_PKG_HEAD_SIZE) + if (pStContext->uiWemqPkgLen >= + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - + C_RMB_MQ_PKG_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] receive reqSize=%u bigger than shmSize=%u,discard", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pStContext->uiWemqPkgLen, + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "receive reqSize bigger than shmSize", + pStContext->pReceiveWemqMsg); + } + else + { + while ((iRet = + rmb_context_enqueue (pStContext, + (const enum RmbMqIndex) iMqIndex, + pStContext->pWemqPkg, + pStContext->uiWemqPkgLen)) == -2) + { + // LOG + LOGRMB (RMB_LOG_DEBUG, "[Type:%d] [TID:%lu] req queue full!wait!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + usleep (1000); + } + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] req wemq_context_enqueue error!enqueue failed=%d!receive=%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "req wemq_context_enqueue error!enqueue failed", + pStContext->pReceiveWemqMsg); + return 0; + } + else + { + LOGRMB (RMB_LOG_DEBUG, "[Type:%d] [TID:%lu] Enqueue succ, msg %s", + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pWemqHeader->cStrJsonBody); + } + } + } + else + { + iRet = + sendto (pStContext->iSocketForReq, pStContext->pWemqPkg, + pStContext->uiWemqPkgLen, 0, + (const struct sockaddr *) &pStContext->tmpReqAddr, + sizeof (pStContext->tmpReqAddr)); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] sendto failed=%d,message is:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + } + } + } + } + + else if (strcmp (usCmd, REQUEST_TO_CLIENT) == 0) //sub端收到RR请求消息 + { + if (serRet == 0) + { + StContext *pStContext; + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pStContext = (StContext *) (pContextProxy->pubContext); + } + else + { + pStContext = (StContext *) (pContextProxy->subContext); + } + + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pStContext is null"); + } + + int iRet = 0; + if ((iRet = + trans_json_2_rmb_msg (pStContext->pReceiveWemqMsg, + pWemqHeader->cStrJsonBody, + REQUEST_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "trans_json_2_rmb_msg failed", + pStContext->pReceiveWemqMsg); + return -1; + } + + pStContext->pReceiveWemqMsg->iMsgMode = RMB_MSG_FROM_WEMQ; + pStContext->pReceiveWemqMsg->cPkgType = QUEUE_PKG; + + pStContext->uiWemqPkgLen = MAX_LENTH_IN_A_MSG; + + set_extfields_2_rmb_msg (pStContext->pReceiveWemqMsg, REQUEST_TO_CLIENT, + seq); + + iRet = + shift_msg_2_buf (pStContext->pWemqPkg, &pStContext->uiWemqPkgLen, + pStContext->pReceiveWemqMsg); + //LOGRMB(RMB_LOG_DEBUG, "uiWemqPkgLen:%d", pStContext->uiWemqPkgLen); + + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "shift_msg_2_buf error!iRet=%d, %d, %s/%s/%s,unique_id=%s,mode=%d,receive=%s", + iRet, pStContext->pReceiveWemqMsg->iEventOrService, + pStContext->pReceiveWemqMsg->strTargetDcn, + pStContext->pReceiveWemqMsg->strServiceId, + pStContext->pReceiveWemqMsg->strScenarioId, + pStContext->pReceiveWemqMsg->sysHeader.cUniqueId, + pStContext->pReceiveWemqMsg->iMsgMode, + rmb_msg_print (pStContext->pReceiveWemqMsg)); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "shift_msg_2_buf failed", + pStContext->pReceiveWemqMsg); + return -1; + } + + int iMqIndex = req_mq_index; + //染色消息直接返回 + if (check_dyed_msg (pStContext->pReceiveWemqMsg) > 0) + { + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", pWemqHeader->cStrJsonBody); + _wemq_thread_dyed_msg_ack_to_access (pThreadCtx, seq, 0, + REQUEST_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsg); + _wemq_thread_dyed_msg_reply_to_access (pThreadCtx, seq, 0, + RESPONSE_TO_SERVER, + pStContext->pReceiveWemqMsg); + return serRet; + } + LOGRMB (RMB_LOG_DEBUG, "WEMQ_CMD_SYNCREQ:Ready to en queue"); + + if (pRmbStConfig->iFlagForReq == (int) MSG_IPC_MQ) + { + //if (bodyLen >= pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - C_RMB_MQ_PKG_HEAD_SIZE) + if (pStContext->uiWemqPkgLen >= + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - + C_RMB_MQ_PKG_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] receive reqSize=%u bigger than shmSize=%u,discard", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pStContext->uiWemqPkgLen, + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "receive reqSize bigger than shmSize", + pStContext->pReceiveWemqMsg); + } + else + { + while ((iRet = + rmb_context_enqueue (pStContext, + (const enum RmbMqIndex) iMqIndex, + pStContext->pWemqPkg, + pStContext->uiWemqPkgLen)) == -2) + { + // LOG + LOGRMB (RMB_LOG_DEBUG, "[Type:%d] [TID:%lu] req queue full!wait!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + usleep (1000); + } + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] req wemq_context_enqueue error!enqueue failed=%d!receive=%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "req wemq_context_enqueue error!enqueue failed", + pStContext->pReceiveWemqMsg); + } + else + { + LOGRMB (RMB_LOG_DEBUG, + "[Type:%d] [TID:%lu] Enqueue succ, msg: header %s body %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pWemqHeader->cStrJsonHeader, pWemqHeader->cStrJsonBody); + } + } + } + else + { + iRet = + sendto (pStContext->iSocketForReq, pStContext->pWemqPkg, + pStContext->uiWemqPkgLen, 0, + (const struct sockaddr *) &pStContext->tmpReqAddr, + sizeof (pStContext->tmpReqAddr)); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] sendto failed=%d,message is:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + } + } + } + } + else if (strcmp (usCmd, RESPONSE_TO_CLIENT) == 0) //rr请求端收到的回包 + { + if (serRet == 0) //rsp succ + { + WEMQJSON *jsonByteBody = NULL; + WEMQJSON *systemHeader = NULL; + WEMQJSON *sysExtFields = NULL; + WEMQJSON *jsonDecoder = NULL; + int rrType = 0; + WEMQJSON *jsonBody = json_tokener_parse (pWemqHeader->cStrJsonBody); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_tokener_parse failed!,buf is:%s", + pWemqHeader->cStrJsonBody); + return -1; + } + if (!json_object_object_get_ex + (jsonBody, MSG_BODY_BYTE_BODY_JSON, &jsonByteBody)) + { + LOGRMB (RMB_LOG_ERROR, "body json no byte body!"); + json_object_put (jsonBody); + return -1; + } //byte body json + + jsonByteBody = + json_tokener_parse (json_object_get_string (jsonByteBody)); + if (NULL == jsonByteBody + || !json_object_object_get_ex (jsonByteBody, + MSG_BODY_BYTE_BODY_SYSTEM_HEADER_CONTENT_JSON, + &systemHeader)) + { + LOGRMB (RMB_LOG_ERROR, "byte body json no system header content!"); + json_object_put (jsonBody); + if (NULL != jsonByteBody) + { + json_object_put (jsonByteBody); + } + return -1; + } //system header json + + systemHeader = + json_tokener_parse (json_object_get_string (systemHeader)); + if (json_object_object_get_ex + (systemHeader, MSG_BODY_SYSTEM_EXTFIELDS_STR, &sysExtFields)) + { + sysExtFields = + json_tokener_parse (json_object_get_string (sysExtFields)); + if (json_object_object_get_ex + (sysExtFields, MSG_BODY_SYSTEM_RRTYPE_INT, &jsonDecoder)) + { + rrType = json_object_get_int (jsonDecoder); + } + } //system extFields RRtype + if (0 == rrType) + { + if (bodyLen >= (TCP_BUF_SIZE * sizeof (char))) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] get rsp too long,bodyLen=%d,buf_le=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, + time, bodyLen, TCP_BUF_SIZE); + } + int i = 0; + int recvFlag = 0; + pthread_mutex_lock (&pContextProxy->rrMutex); + if (pContextProxy->iFlagForRR == -1) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] signal succ! iFlagForRR=0", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, + time); + memcpy (pContextProxy->mPubRRBuf, pWemqHeader->cStrJsonBody, + bodyLen); + pContextProxy->mPubRRBuf[bodyLen] = '\0'; + trans_json_2_rmb_msg (pContextProxy->pReplyMsg, + pContextProxy->mPubRRBuf, RESPONSE_TO_CLIENT); + //LOGRMB(RMB_LOG_DEBUG, "destname :%s", pContextProxy->pReplyMsg->dest.cDestName); + GetRmbNowLongTime (); + pContextProxy->pReplyMsg->sysHeader.ulReplyReceiveTime = + pRmbStConfig->ulNowTtime; + set_extfields_2_rmb_msg (pContextProxy->pReplyMsg, + RESPONSE_TO_CLIENT, seq); + if (pContextProxy->stUnique.flag == 1 + && strcmp (pContextProxy->stUnique.unique_id, + pContextProxy->pReplyMsg->sysHeader.cUniqueId) == 0) + { + if (check_dyed_msg (pContextProxy->pReplyMsg) > 0) + { + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", + pContextProxy->mPubRRBuf); + pContextProxy->iFlagForRR = RMB_CODE_DYED_MSG; + } + else + { + pContextProxy->iFlagForRR = serRet; + } + pContextProxy->stUnique.flag = 0; + pthread_cond_signal (&pContextProxy->rrCond); + recvFlag = 1; + + } + } + pthread_mutex_unlock (&pContextProxy->rrMutex); + if (recvFlag == 1) + { + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, 0, + RESPONSE_TO_CLIENT_ACK, + pContextProxy->pReplyMsg); + //_wemq_thread_send_error_log(pThreadCtx, seq, 0, "ok", pContextProxy->pReplyMsg); + } + } + else //case WEMQ_CMD_ASYNCRSP RR异步消息,服务请求方收到回包 + { + StContext *pStContext = (StContext *) (pContextProxy->subContext); + pContextProxy->iFlagForRRAsync = 0; + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "[TID:%lu] pStContext is null", + pThreadCtx->m_threadID); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return -1; + } + + int iRet = 0; + + if ((iRet = + trans_json_2_rmb_msg (pStContext->pReceiveWemqMsgForRR, + pWemqHeader->cStrJsonBody, + RESPONSE_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pWemqHeader->cStrJsonBody); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, -1, + RESPONSE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsgForRR); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "trans_json_2_rmb_msg failed", + pStContext->pReceiveWemqMsgForRR); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return -1; + } + GetRmbNowLongTime (); + pStContext->pReceiveWemqMsgForRR->sysHeader.ulReplyReceiveTime = + pRmbStConfig->ulNowTtime; + int i; + set_extfields_2_rmb_msg (pStContext->pReceiveWemqMsgForRR, + RESPONSE_TO_CLIENT, seq); + int recvFlag = 0; + pthread_mutex_lock (&pContextProxy->rrMutex); + //因为在access goodbye的时候,消息可能在旧连接上,所以必须同时扫描新旧连接,不能只扫描新连接 + + //if(isRecvNewConnect) + //{ + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncNew. + get_array_size (&pContextProxy->pUniqueListForRRAsyncNew); i++) + { + if (pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag == 1 + && strcmp (pContextProxy->pUniqueListForRRAsyncNew.Data[i]. + unique_id, + pStContext->pReceiveWemqMsgForRR->sysHeader. + cUniqueId) == 0) + { + pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag = 0; + recvFlag = 1; + break; + } + } + // }else + // { + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncOld. + get_array_size (&pContextProxy->pUniqueListForRRAsyncOld); i++) + { + if (pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag == 1 + && strcmp (pContextProxy->pUniqueListForRRAsyncOld.Data[i]. + unique_id, + pStContext->pReceiveWemqMsgForRR->sysHeader. + cUniqueId) == 0) + { + pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag = 0; + recvFlag = 1; + break; + } + } + pthread_mutex_unlock (&pContextProxy->rrMutex); + //} + //已经超时,不回包给pub端 + if (recvFlag == 0) + { + LOGRMB (RMB_LOG_WARN, + "rr async response bizseq=%s, uniqueId=%s comes back, but request has timeout", + pStContext->pReceiveWemqMsgForRR->sysHeader.cBizSeqNo, + pStContext->pReceiveWemqMsgForRR->sysHeader.cUniqueId); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return -1; + } + + pStContext->pReceiveWemqMsgForRR->cPkgType = RR_TOPIC_PKG; + pStContext->pReceiveWemqMsgForRR->iMsgMode = RMB_MSG_FROM_WEMQ; + pStContext->uiWemqPkgForRRAsyncLen = MAX_LENTH_IN_A_MSG; + iRet = + shift_msg_2_buf (pStContext->pWemqPkgForRRAsync, + &pStContext->uiWemqPkgForRRAsyncLen, + pStContext->pReceiveWemqMsgForRR); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "shift_msg_2_buf error!iRet=%d, %d, %s/%s/%s,unique_id=%s,mode=%d,receive=%s", + iRet, pStContext->pReceiveWemqMsgForRR->iEventOrService, + pStContext->pReceiveWemqMsgForRR->strTargetDcn, + pStContext->pReceiveWemqMsgForRR->strServiceId, + pStContext->pReceiveWemqMsgForRR->strScenarioId, + pStContext->pReceiveWemqMsgForRR->sysHeader.cUniqueId, + pStContext->pReceiveWemqMsgForRR->iMsgMode, + rmb_msg_print (pStContext->pReceiveWemqMsgForRR)); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, -1, + RESPONSE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsgForRR); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "shift_msg_2_buf error", + pStContext->pReceiveWemqMsgForRR); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return -1; + } + if (check_dyed_msg (pStContext->pReceiveWemqMsgForRR) > 0) + { + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", + pWemqHeader->cStrJsonBody); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, 0, + RESPONSE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsgForRR); + json_object_put (jsonBody); + json_object_put (jsonByteBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + return serRet; + } + + int iMqIndex = rr_rsp_mq_index; + LOGRMB (RMB_LOG_DEBUG, + "WEMQ_CMD_ASYNCRSP:Recv rr rsp Ready to en queue"); + if (pRmbStConfig->iFlagForRRrsp == (int) MSG_IPC_MQ) + { + if (pStContext->uiWemqPkgForRRAsyncLen >= + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - + C_RMB_MQ_PKG_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] receive reqSize=%u bigger than shmSize=%u,discard", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pStContext->uiWemqPkgForRRAsyncLen, + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, -1, + RESPONSE_TO_CLIENT_ACK, + pStContext-> + pReceiveWemqMsgForRR); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "receive msg bigger than shmSize", + pStContext->pReceiveWemqMsgForRR); + } + else + { + while ((iRet = + rmb_context_enqueue (pStContext, + (const enum RmbMqIndex) iMqIndex, + pStContext->pWemqPkgForRRAsync, + pStContext-> + uiWemqPkgForRRAsyncLen)) == -2) + { + // LOG + LOGRMB (RMB_LOG_DEBUG, + "[Type:%d] [TID:%lu] req queue full!wait!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + usleep (1000); + } + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] req wemq_context_enqueue error!enqueue failed=%d!receive=%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, -1, + RESPONSE_TO_CLIENT_ACK, + pStContext-> + pReceiveWemqMsgForRR); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, + LOG_ERROR_POINT, + "req wemq_context_enqueue error", + pStContext->pReceiveWemqMsgForRR); + } + else + { + LOGRMB (RMB_LOG_DEBUG, + "[Type:%d] [TID:%lu] Enqueue succ, msg: header %s body %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pWemqHeader->cStrJsonHeader, pWemqHeader->cStrJsonBody); + _wemq_thread_resp_ack_to_access (pThreadCtx, seq, 0, + RESPONSE_TO_CLIENT_ACK, + pStContext-> + pReceiveWemqMsgForRR); + } + } + } + else + { + iRet = + sendto (pStContext->iSocketForRsp, pStContext->pWemqPkgForRRAsync, + pStContext->uiWemqPkgForRRAsyncLen, 0, + (const struct sockaddr *) &pStContext->tmpReplyAddr, + sizeof (pStContext->tmpReplyAddr)); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] sendto failed=%d,message is:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + } + } + } + json_object_put (jsonByteBody); + json_object_put (jsonBody); + if (NULL != systemHeader) + { + json_object_put (systemHeader); + } + if (NULL != sysExtFields) + { + json_object_put (sysExtFields); + } + } + else if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] rr request ret Authentication fail", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + pthread_mutex_lock (&pContextProxy->rrMutex); + pContextProxy->iFlagForRR = serRet; + pContextProxy->stUnique.flag = 0; + pthread_cond_signal (&pContextProxy->rrCond); + pthread_mutex_unlock (&pContextProxy->rrMutex); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] rr request ret fail", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + pthread_mutex_lock (&pContextProxy->rrMutex); + pContextProxy->iFlagForRR = serRet; + pContextProxy->stUnique.flag = 0; + pthread_cond_signal (&pContextProxy->rrCond); + pthread_mutex_unlock (&pContextProxy->rrMutex); + } + } + else if (strcmp (usCmd, BROADCAST_MESSAGE_TO_SERVER_ACK) == 0) //收到广播消息的ack + { + if (serRet == RMB_CODE_SUSS) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Publish Broadcast Message request success", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + } + else if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Publish Broadcast Message request Authentication fail!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Publish Broadcast Message request failed!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + } + + pthread_mutex_lock (&pContextProxy->eventMutex); + if (pContextProxy->iFlagForEvent == -1) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] send Broadcast msg signal succ! iFlagForEvent=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + serRet); + LOGRMB (RMB_LOG_DEBUG, "seq for Broadcast: %d", + pContextProxy->iSeqForEvent); + if (seq == pContextProxy->iSeqForEvent) + { + pContextProxy->iFlagForEvent = serRet; + pthread_cond_signal (&pContextProxy->eventCond); + } + } + pthread_mutex_unlock (&pContextProxy->eventMutex); + } + + else if (strcmp (usCmd, BROADCAST_MESSAGE_TO_CLIENT) == 0) //收到广播消息 + { + if (serRet == 0) + { + StContext *pStContext = NULL; + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pStContext = (StContext *) (pContextProxy->pubContext); + } + else + { + pStContext = (StContext *) (pContextProxy->subContext); + } + + if (pStContext == NULL) + { + LOGRMB (RMB_LOG_ERROR, "[TID:%lu] pStContext is null", + pThreadCtx->m_threadID); + return -1; + } + + int iRet = 0; + + if ((iRet = + trans_json_2_rmb_msg (pStContext->pReceiveWemqMsgForBroadCast, + pWemqHeader->cStrJsonBody, + BROADCAST_MESSAGE_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pWemqHeader->cStrJsonBody); + return -1; + } + + pStContext->pReceiveWemqMsgForBroadCast->cPkgType = BROADCAST_TOPIC_PKG; + pStContext->pReceiveWemqMsgForBroadCast->iMsgMode = RMB_MSG_FROM_WEMQ; + pStContext->uiWemqPkgLen = MAX_LENTH_IN_A_MSG; + + set_extfields_2_rmb_msg (pStContext->pReceiveWemqMsgForBroadCast, + BROADCAST_MESSAGE_TO_CLIENT, seq); + + iRet = + shift_msg_2_buf (pStContext->pWemqPkg, &pStContext->uiWemqPkgLen, + pStContext->pReceiveWemqMsgForBroadCast); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "shift_msg_2_buf error!iRet=%d, %d, %s/%s/%s,unique_id=%s,mode=%d,receive=%s", + iRet, + pStContext->pReceiveWemqMsgForBroadCast->iEventOrService, + pStContext->pReceiveWemqMsgForBroadCast->strTargetDcn, + pStContext->pReceiveWemqMsgForBroadCast->strServiceId, + pStContext->pReceiveWemqMsgForBroadCast->strScenarioId, + pStContext->pReceiveWemqMsgForBroadCast->sysHeader.cUniqueId, + pStContext->pReceiveWemqMsgForBroadCast->iMsgMode, + rmb_msg_print (pStContext->pReceiveWemqMsgForBroadCast)); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "shift_msg_2_buf error", + pStContext->pReceiveWemqMsgForBroadCast); + + return -1; + } + //染色消息直接返回 + if (check_dyed_msg (pStContext->pReceiveWemqMsgForBroadCast) > 0) + { + _wemq_thread_dyed_msg_ack_to_access (pThreadCtx, seq, 0, + BROADCAST_MESSAGE_TO_CLIENT_ACK, + pStContext->pReceiveWemqMsg); + LOGRMB (RMB_LOG_DEBUG, "get dyed msg:%s", pWemqHeader->cStrJsonBody); + return serRet; + } + + int iMqIndex = broadcast_mq_index; + LOGRMB (RMB_LOG_DEBUG, + "WEMQ_CMD_BROADCAST_SUB:Recv broadcast message ready to enqueue"); + if (pRmbStConfig->iFlagForBroadCast == (int) MSG_IPC_MQ) + { + if (pStContext->uiWemqPkgLen >= + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize - + C_RMB_MQ_PKG_HEAD_SIZE) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] receive broadcast message reqSize=%u bigger than shmSize=%u,discard", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pStContext->uiWemqPkgLen, + pStContext->fifoMq.mqIndex[iMqIndex]->mq->uiBlockSize); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "receive broadcast message reqSize bigger than shmSize", + pStContext-> + pReceiveWemqMsgForBroadCast); + } + else + { + while ((iRet = + rmb_context_enqueue (pStContext, + (const enum RmbMqIndex) iMqIndex, + pStContext->pWemqPkg, + pStContext->uiWemqPkgLen)) == -2) + { + //queue full + LOGRMB (RMB_LOG_ERROR, "[Type:%d] [TID:%lu] req queue full!wait!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + usleep (1000); + } + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] req rmb_context_enqueue error!iRet=%d!receive=%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + _wemq_thread_send_error_log (pThreadCtx, seq, -1, LOG_ERROR_POINT, + "req rmb_context_enqueue error", + pStContext-> + pReceiveWemqMsgForBroadCast); + } + else + { + LOGRMB (RMB_LOG_DEBUG, + "[Type:%d] [TID:%lu] enqueue succ, msg: header %s body %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pWemqHeader->cStrJsonHeader, pWemqHeader->cStrJsonBody); + } + } + } + else + { + iRet = + sendto (pStContext->iSocketForBroadcast, pStContext->pWemqPkg, + pStContext->uiWemqPkgLen, 0, + (const struct sockaddr *) &pStContext->tmpBroadcastAddr, + sizeof (pStContext->tmpBroadcastAddr)); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] udp error!sendto failed=%d!receive message:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRet, + pWemqHeader->cStrJsonBody); + } + } + } + } + else if (strcmp (usCmd, SUBSCRIBE_RESPONSE) == 0) // add subscribe response + { + if (serRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] add listen return failed, iRet=%d, errmsg=%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, serRet, cMsg); + } + + pthread_mutex_lock (&pContextProxy->regMutex); + if (pContextProxy->iFlagForReg == 0) + { + pContextProxy->iFlagForReg = 1; + pContextProxy->iResultForReg = serRet; + pthread_cond_signal (&pContextProxy->regCond); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + } + else if (strcmp (usCmd, LISTEN_RESPONSE) == 0) // add listen start response + { + + if (serRet == RMB_CODE_OTHER_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] send start to access failed,iRet=%d, errmsg=%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, serRet, cMsg); + } + + if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] send start to access authentication failed,iRet=%d, errmsg=%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, serRet, cMsg); + } + + pthread_mutex_lock (&pContextProxy->regMutex); + if (pContextProxy->iFlagForReg == 0) + { + pContextProxy->iFlagForReg = 1; + pContextProxy->iResultForReg = serRet; + pthread_cond_signal (&pContextProxy->regCond); + } + pthread_mutex_unlock (&pContextProxy->regMutex); + + } + + else + { + LOGRMB (RMB_LOG_ERROR, "[%s] [Type:%d] [TID:%lu] No Such Command:%s!", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, usCmd); + ret = -1; + } + + json_object_put (jsonHeader); + + return ret; +} + +static int32_t _wemq_thread_do_recv_sync (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + int timeout = pRmbStConfig->iWemqTcpSocketTimeout; + + unsigned int uiTimeOutTimes = 0; + unsigned int uiClosedByPeerTimes = 0; + while (1) + { + uint32_t iRecvLen; + int iRet = + wemq_tcp_recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff, + &iRecvLen, timeout, pThreadCtx->ssl); + if (iRet == 0) + { + uiTimeOutTimes += 1; + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP recv timeout!timeout_times=%u, fd=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + uiTimeOutTimes, pThreadCtx->m_iSockFd); + if (uiTimeOutTimes >= 12) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP continuity recv timeout times=%d, so close connect", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + uiTimeOutTimes); + uiTimeOutTimes = 0; + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + wemq_proxy_to_black_list (pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return -2; + } + continue; + } + else if (iRet == -2) + { + uiClosedByPeerTimes += 1; + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP conncet closed by peer(%d)", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, errno); + if (uiClosedByPeerTimes >= 3) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP conncet continuity closed by peer times=%d, so close connect", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + uiClosedByPeerTimes); + uiClosedByPeerTimes = 0; + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + wemq_proxy_to_black_list (pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return -2; + } + continue; + } + else if (iRet == -3) + { + // msg is not full + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] msg is not full", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + + return 1; + } + else if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] wemq_tcp_recv error", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return -1; + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] recv complete len %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, iRet); + + //memset(&pThreadCtx->m_stWeMQMSG, 0, sizeof(pThreadCtx->m_stWeMQMSG)); + memset (&pThreadCtx->m_stWeMQMSG, 0, (sizeof (int) * 2)); + DecodeWeMQMsg (&pThreadCtx->m_stWeMQMSG, pThreadCtx->m_pRecvBuff, iRet); + if (pThreadCtx->m_stWeMQMSG.uiHeaderLen == 0 + || pThreadCtx->m_stWeMQMSG.uiHeaderLen >= MAX_WEMQ_HEADER_LEN) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] recv header len %u is 0 or too long", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_stWeMQMSG.uiHeaderLen); + return -1; + } + if (pThreadCtx->m_stWeMQMSG.uiHeaderLen > 0) + { + memcpy (pThreadCtx->m_stWeMQMSG.cStrJsonHeader, + pThreadCtx->m_pRecvBuff + 8, + pThreadCtx->m_stWeMQMSG.uiHeaderLen); + pThreadCtx->m_stWeMQMSG.cStrJsonHeader[pThreadCtx->m_stWeMQMSG. + uiHeaderLen] = '\0'; + } + unsigned int uiTmpBodyLen = + pThreadCtx->m_stWeMQMSG.uiTotalLen - + pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8; + if (uiTmpBodyLen >= MAX_WEMQ_BODY_LEN) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] recv body len %d is too long", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + uiTmpBodyLen); + return -1; + } + if (uiTmpBodyLen == 0) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] recv body len is 0", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + } + //if (pThreadCtx->m_stWeMQMSG.uiTotalLen - pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8 > 0) + if (uiTmpBodyLen > 0) + { + memcpy (pThreadCtx->m_stWeMQMSG.cStrJsonBody, + pThreadCtx->m_pRecvBuff + 8 + + pThreadCtx->m_stWeMQMSG.uiHeaderLen, + pThreadCtx->m_stWeMQMSG.uiTotalLen - + pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8); + pThreadCtx->m_stWeMQMSG.cStrJsonBody[uiTmpBodyLen] = '\0'; + } + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header complete,total len %d, header len %d,header %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_stWeMQMSG.uiTotalLen, + pThreadCtx->m_stWeMQMSG.uiHeaderLen, + pThreadCtx->m_stWeMQMSG.cStrJsonHeader); + return 0; + } + return -1; +} + +static int32_t _wemq_thread_do_recv_async (WemqThreadCtx * pThreadCtx, + bool isRecvNewConnect) +{ + ASSERT (pThreadCtx); + + int nfds = + epoll_wait (pThreadCtx->m_iEpollFd, pThreadCtx->m_ptEvents, MAX_EVENTS, + 1); + if (nfds == -1) + { + LOGRMB (RMB_LOG_ERROR, "[%s] [Type:%d] [TID:%lu] epoll wait error:%d!", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, errno); + return -1; + } + if (nfds == 0) + { + return 0; + } + + unsigned long ulLastTime = 0; + unsigned long ulNowTime = 0; + struct timeval tv; + + int iTmp = 0; + int iRecvd = 0; + int iRemind = TCP_PKG_LEN_BTYES; + + for (iTmp = 0; iTmp < nfds; ++iTmp) + { + // 必须在此判断,如果新旧连接都有消息过来,后面会把当前fd改成新连接的fd,导致下次循环又会重新处理 + if (!isRecvNewConnect) + { + pThreadCtx->m_iSockFdNew = pThreadCtx->m_iSockFd; + pThreadCtx->sslNew = pThreadCtx->ssl; + pThreadCtx->m_iSockFd = pThreadCtx->m_iSockFdOld; + pThreadCtx->ssl = pThreadCtx->sslOld; + } + + if (pThreadCtx->m_ptEvents[iTmp].data.fd == pThreadCtx->m_iSockFd) + { + if (EPOLLIN == (pThreadCtx->m_ptEvents[iTmp].events & EPOLLIN)) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] EPOLLIN EVENT", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + gettimeofday (&tv, NULL); + ulLastTime = tv.tv_sec * 1000000 + tv.tv_usec; + ulNowTime = ulLastTime; + while (iRemind > 0) + { + int iRecv; + if (NULL != pThreadCtx->ssl) + { + iRecv = + SSL_read (pThreadCtx->ssl, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind); + } + else + { + iRecv = + recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind, 0); + } + //if (iRecv < 0 && (errno != EAGAIN)) + if (iRecv < 0) + { + if (errno == EAGAIN) + { + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + if ((ulNowTime - ulLastTime) > (1 * 60 * 1000000)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + usleep (100); + continue; + } + + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Peer close connect, fd close() ret=%d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, iRecv); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv > 0) + { + iRecvd += iRecv; + iRemind -= iRecv; + } + } + + if (iRecvd != 4 || strcmp (pThreadCtx->m_pRecvBuff, "WEMQ") != 0) + { + if (!isRecvNewConnect) + { + LOGRMB (RMB_LOG_ERROR, "IP: [old proxy ip:%s|old port:%d]", + pThreadCtx->m_cProxyIPOld, pThreadCtx->m_uiProxyPortOld); + } + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%d] recv header error, buf: %s, len: %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_pRecvBuff, iRecvd); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + gettimeofday (&tv, NULL); + ulLastTime = tv.tv_sec * 1000000 + tv.tv_usec; + ulNowTime = ulLastTime; + iRecvd = 0; + iRemind = TCP_PKG_LEN_BTYES; + while (iRemind > 0) + { + int iRecv; + if (NULL != pThreadCtx->ssl) + { + iRecv = + SSL_read (pThreadCtx->ssl, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind); + } + else + { + iRecv = + recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind, 0); + } + //if (iRecv < 0 && (errno != EAGAIN)) + if (iRecv < 0) + { + if (errno == EAGAIN) + { + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + if ((ulNowTime - ulLastTime) > (1 * 60 * 1000000)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + usleep (100); + continue; + } + + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Peer close connect, fd close() ret=%d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, iRecv); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv > 0) + { + iRecvd += iRecv; + iRemind -= iRecv; + } + } + + if (iRecvd != 4) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%d] recv version error, version=%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_pRecvBuff); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + gettimeofday (&tv, NULL); + ulLastTime = tv.tv_sec * 1000000 + tv.tv_usec; + ulNowTime = ulLastTime; + + iRecvd = 0; + iRemind = TCP_PKG_LEN_BTYES; + while (iRemind > 0) + { + int iRecv; + if (NULL != pThreadCtx->ssl) + { + iRecv = + SSL_read (pThreadCtx->ssl, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind); + } + else + { + iRecv = + recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind, 0); + } + //if (iRecv < 0 && (errno != EAGAIN)) + if (iRecv < 0) + { + if (errno == EAGAIN) + { + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + if ((ulNowTime - ulLastTime) > (1 * 60 * 1000000)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + usleep (100); + continue; + } + + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Peer close connect, fd close() ret=%d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, iRecv); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv > 0) + { + iRecvd += iRecv; + iRemind -= iRecv; + } + } + //ASSERT (iRemind == 0); + if (iRemind != 0 || iRecvd != TCP_PKG_LEN_BTYES) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] get msg length failed", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + gettimeofday (&tv, NULL); + ulLastTime = tv.tv_sec * 1000000 + tv.tv_usec; + ulNowTime = ulLastTime; + + iRemind = ntohl (*(uint32_t *) pThreadCtx->m_pRecvBuff); + iRemind -= TCP_PKG_LEN_BTYES; + while (iRemind > 0) + { + int iRecv; + if (NULL != pThreadCtx->ssl) + { + iRecv = + SSL_read (pThreadCtx->ssl, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind); + } + else + { + iRecv = + recv (pThreadCtx->m_iSockFd, pThreadCtx->m_pRecvBuff + iRecvd, + iRemind, 0); + } + //if (iRecv < 0 && (errno != EAGAIN)) + if (iRecv < 0) + { + if (errno == EAGAIN) + { + gettimeofday (&tv, NULL); + ulNowTime = tv.tv_sec * 1000000 + tv.tv_usec; + if ((ulNowTime - ulLastTime) > (1 * 60 * 1000000)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + usleep (100); + continue; + } + + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv return < 0, errno %d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, errno); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + + if (iRecv == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Peer close connect, fd close() ret=%d", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, iRecv); + _wemq_thread_reset_sockFd (pThreadCtx, isRecvNewConnect); + return -2; + } + if (iRecv > 0) + { + iRecvd += iRecv; + iRemind -= iRecv; + } + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] recv complete len %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, iRecvd); + if (!isRecvNewConnect) + { + pThreadCtx->m_iSockFd = pThreadCtx->m_iSockFdNew; + pThreadCtx->ssl = pThreadCtx->sslNew; + } + //memset(&pThreadCtx->m_stWeMQMSG, 0, sizeof(pThreadCtx->m_stWeMQMSG)); + memset (&pThreadCtx->m_stWeMQMSG, 0, (sizeof (int) * 2)); + int iRet = + DecodeWeMQMsg (&pThreadCtx->m_stWeMQMSG, pThreadCtx->m_pRecvBuff, + iRecvd); + + if (pThreadCtx->m_stWeMQMSG.uiHeaderLen == 0 + || pThreadCtx->m_stWeMQMSG.uiHeaderLen >= MAX_WEMQ_HEADER_LEN) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header complete, header len %d is 0 or too long", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_stWeMQMSG.uiHeaderLen); + return -1; + } + if (pThreadCtx->m_stWeMQMSG.uiHeaderLen > 0) + { + memcpy (pThreadCtx->m_stWeMQMSG.cStrJsonHeader, + pThreadCtx->m_pRecvBuff + 8, + pThreadCtx->m_stWeMQMSG.uiHeaderLen); + pThreadCtx->m_stWeMQMSG.cStrJsonHeader[pThreadCtx->m_stWeMQMSG. + uiHeaderLen] = '\0'; + } + LOGRMB (RMB_LOG_DEBUG, "cStrJsonHeader: %s", + pThreadCtx->m_stWeMQMSG.cStrJsonHeader); + unsigned int uiTmpBodyLen = + pThreadCtx->m_stWeMQMSG.uiTotalLen - + pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8; + if (uiTmpBodyLen >= MAX_WEMQ_BODY_LEN) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq complete,body len %d is too long", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + uiTmpBodyLen); + return -1; + } + if (uiTmpBodyLen == 0) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq complete,body len is 0", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + } + //if (pThreadCtx->m_stWeMQMSG.uiTotalLen - pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8 > 0) + if (uiTmpBodyLen > 0) + { + //set message source + pThreadCtx->m_stWeMQMSG.cStrJsonBody[0] = RMB_MSG_FROM_WEMQ; + memcpy (pThreadCtx->m_stWeMQMSG.cStrJsonBody, + pThreadCtx->m_pRecvBuff + 8 + + pThreadCtx->m_stWeMQMSG.uiHeaderLen, + pThreadCtx->m_stWeMQMSG.uiTotalLen - + pThreadCtx->m_stWeMQMSG.uiHeaderLen - 8); + pThreadCtx->m_stWeMQMSG.cStrJsonBody[uiTmpBodyLen] = '\0'; + } + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header complete,total len %d, header len %d,header %s, body %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_stWeMQMSG.uiTotalLen, + pThreadCtx->m_stWeMQMSG.uiHeaderLen, + pThreadCtx->m_stWeMQMSG.cStrJsonHeader, + pThreadCtx->m_stWeMQMSG.cStrJsonBody); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -1; + } + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] epoll events %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_ptEvents[iTmp].events); + } + + } + if (!isRecvNewConnect) + { + pThreadCtx->m_iSockFd = pThreadCtx->m_iSockFdNew; + pThreadCtx->ssl = pThreadCtx->sslNew; + } + } + return iRecvd; +} + +static int32_t _wemq_thread_do_send_sync (WemqThreadCtx * pThreadCtx, + void *msg, uint32_t totalLen, + uint32_t headerLen) +{ + int iRetry = 2; + int timeout = pRmbStConfig->iWemqTcpSocketTimeout; + + while (iRetry > 0) + { + int iRet = + wemq_tcp_send (pThreadCtx->m_iSockFd, msg, totalLen, headerLen, timeout, + pThreadCtx->ssl); + + if (iRet == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Retry: %d] TCP send timeout!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, iRetry); + iRetry--; + continue; + } + else if (iRet == -2) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] TCP send error(%d)!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, errno); + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + return -1; + } + else if (iRet > 0) + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] send complete len %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, iRet); + return 0; + } + return -2; + } + + // 重试2次失败 + return -3; +} + +static int32_t _wemq_thread_do_cmd_add_listen_msg (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_ADD_LISTEN); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s, body:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] _wemq_thread_do_send_sync error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_start_msg (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_START); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] _wemq_thread_do_send_sync error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_client_goodbye_msg (WemqThreadCtx * + pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_CLIENT_GOODBYE); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send Client GoodBye:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] _wemq_thread_do_send_sync client goodbye error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_msg (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_MSG); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + if (NULL != pStWemqThreadMsg->m_pBody) + { + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s body:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_log (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_LOG); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + if (NULL != pStWemqThreadMsg->m_pBody) + { + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + } + + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Send:%s\n", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, pStWemqThreadMsg->m_pHeader); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_async_request (WemqThreadCtx * + pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_REQUEST_ASYNC); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s body:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_request (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_REQUEST); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s body:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_reply (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_REPLY); + + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss|Send header:%s body:%s\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody); + + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!\n", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_do_cmd_send_msg_ack (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ + ASSERT (pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_SEND_MSG_ACK); + int iRet = 0; + StRmbMsg *pSendMsg = rmb_msg_malloc (); + if ((iRet = + trans_json_2_rmb_msg (pSendMsg, pStWemqThreadMsg->m_pBody, + REQUEST_TO_CLIENT)) != 0) + { + LOGRMB (RMB_LOG_ERROR, "trans_json_2_rmb_msg failed,buf is:%s", + pStWemqThreadMsg->m_pBody); + return -1; + } + pSendMsg->iMsgMode = RMB_MSG_FROM_WEMQ; + pSendMsg->cPkgType = QUEUE_PKG; + + WEMQJSON *jsonDecoder = NULL; + WEMQJSON *sysExtFields = NULL; + int ack_seq = 0; + sysExtFields = json_tokener_parse (pSendMsg->sysHeader.cExtFields); + + if (json_object_object_get_ex + (sysExtFields, MSG_BODY_SYSTEM_ACK_SEQ, &jsonDecoder)) + { + ack_seq = json_object_get_int (jsonDecoder); + } + else + { + LOGRMB (RMB_LOG_ERROR, "get ack_seq failed!"); + return -1; + } + + switch (*(pSendMsg->strServiceId + 3)) + { + case '0': + iRet = + _wemq_thread_resp_ack_to_access (pThreadCtx, ack_seq, 0, + REQUEST_TO_CLIENT_ACK, pSendMsg); + break; + case '1': + iRet = + _wemq_thread_resp_ack_to_access (pThreadCtx, ack_seq, 0, + ASYNC_MESSAGE_TO_CLIENT_ACK, pSendMsg); + break; + case '3': + iRet = + _wemq_thread_resp_ack_to_access (pThreadCtx, ack_seq, 0, + BROADCAST_MESSAGE_TO_CLIENT_ACK, + pSendMsg); + break; + case '4': + iRet = + _wemq_thread_resp_ack_to_access (pThreadCtx, ack_seq, 0, + BROADCAST_MESSAGE_TO_CLIENT_ACK, + pSendMsg); + break; + default: + ; + } + + json_object_put (sysExtFields); + rmb_msg_free (pSendMsg); + + return iRet; +} + +static int32_t _wemq_thread_do_cmd_send_msg_reg (WemqThreadCtx * pThreadCtx) +{ + StWemqThreadMsg *pStWemqThreadMsg = &pThreadCtx->m_stHelloWord; + int iRet = -1; + int iTotalLen = + pStWemqThreadMsg->m_iHeaderLen + pStWemqThreadMsg->m_iBodyLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pBody, + pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] |wemq_thread2accesss| Send header:%s, body:%s, totalLen:%d, headerLen:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pStWemqThreadMsg->m_pHeader, pStWemqThreadMsg->m_pBody, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + //return _wemq_thread_state_trans(pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_BREAK); + return -1; + } + + iRet = _wemq_thread_do_recv_sync (pThreadCtx); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_recv_sync error: %d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, iRet); + return -2; + } + + StWeMQMSG *pWemqHeader = &pThreadCtx->m_stWeMQMSG; + WEMQJSON *jsonHeader = NULL; + WEMQJSON *jsonTmp = NULL; + int usCmd = -1; + int serRet = -1; + int seq = -1; + long time = 0; + char cMessage[100]; + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] |access2wemq_thread|Recv: %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pWemqHeader->cStrJsonHeader); + jsonHeader = json_tokener_parse (pWemqHeader->cStrJsonHeader); + if (jsonHeader == NULL) + { + // 消息不完整, json解析失败 + LOGRMB (RMB_LOG_ERROR, "[Type:%d] [TID:%lu] json_tokener_parse error: %s", + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pWemqHeader->cStrJsonHeader) return 1; + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_COMMAND_STR, &jsonTmp); + if (jsonTmp != NULL) + { + usCmd = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_CODE_INT, &jsonTmp); + if (jsonTmp != NULL) + { + serRet = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_SEQ_INT, &jsonTmp); + if (jsonTmp != NULL) + { + seq = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_TIME_LINT, &jsonTmp); + if (jsonTmp != NULL) + { + time = (long) json_object_get_int64 (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_MSG_STR, &jsonTmp); + if (jsonTmp != NULL) + { + memset (cMessage, 0x00, sizeof (cMessage)); + strncpy (cMessage, json_object_get_string (jsonTmp), + sizeof (cMessage) - 1); + } + json_object_put (jsonHeader); + + if (strcmp (cMessage, "auth exception") == 0) + { // wemq user/passwd error + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] Authentication error!user:%s, passwd:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + pRmbStConfig->cWemqUser, pRmbStConfig->cWemqPasswd); + return -1; + } + if (serRet == RMB_CODE_OTHER_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] register proxy error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + serRet); + return -2; + } + + if (serRet == RMB_CODE_AUT_FAIL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] register proxy Authentication error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time, + serRet); + return -3; + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [Time:%ld] register proxy success!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, time); + + //hello world之后,心跳包可以延期 + gettimeofday (&pThreadCtx->stTimeLast, NULL); + gettimeofday (&pThreadCtx->stTimeLastRecv, NULL); + + return 0; + +} + +int wemq_thread_fifo_msg_is_empty (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx is null"); + return 0; + } + + /** + * fix bug:rmb_sub_reply的消息也需要上传完毕 + */ +// if ((pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) && (pThreadCtx->m_ptFifo != NULL)) { + //check wemq thrad msg empty + if (pThreadCtx->m_ptFifo != NULL) + { + if (wemq_kfifo_is_empty (pThreadCtx->m_ptFifo)) + { + LOGRMB (RMB_LOG_INFO, "pub:pThreadCtx->m_ptFifo is empty"); + return 0; + } + else + { + return 1; + } + } + + return 0; +} + +int wemq_thread_mq_msg_is_empty (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx==NULL"); + return NULL; + } + int result = wemq_thread_check_req_mq_is_null (pThreadCtx) + && wemq_thread_check_rr_rsp_mq_is_null (pThreadCtx) + && wemq_thread_check_broadcast_mq_is_null (pThreadCtx); + if (result == 0) + { + LOGRMB (RMB_LOG_INFO, "wemq_thread_mq_msg_is_empty"); + } + return result; + +} + +StMqInfo *wemq_thread_get_mq_by_type (WemqThreadCtx * pThreadCtx, int iType) +{ + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + StContext *pStContext; + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pStContext = (StContext *) (pContextProxy->pubContext); + } + else + { + pStContext = (StContext *) (pContextProxy->subContext); + } + + return pStContext->fifoMq.mqIndex[iType]; +} + +StMqInfo *wemq_thread_get_receve_req_mq (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx==NULL"); + return NULL; + } + return wemq_thread_get_mq_by_type (pThreadCtx, (int) req_mq_index); +} + +StMqInfo *wemq_thread_get_rr_rsp_mq (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx==NULL"); + return NULL; + } + return wemq_thread_get_mq_by_type (pThreadCtx, (int) rr_rsp_mq_index); +} + +StMqInfo *wemq_thread_get_broadcast_mq (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx==NULL"); + return NULL; + } + return wemq_thread_get_mq_by_type (pThreadCtx, (int) broadcast_mq_index); +} + +/* +Function: rmb_sub_check_req_mq_is_null +Description:校验是否请求队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int wemq_thread_check_req_mq_is_null (WemqThreadCtx * pThreadCtx) +{ + StMqInfo *p = wemq_thread_get_receve_req_mq (pThreadCtx); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/* +Function: wemq_thread_check_rr_rsp_mq_is_null +Description:校验rr_rsp队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int wemq_thread_check_rr_rsp_mq_is_null (WemqThreadCtx * pThreadCtx) +{ + StMqInfo *p = wemq_thread_get_rr_rsp_mq (pThreadCtx); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +/* +Function: wemq_thread_check_broadcast_mq_is_null +Description:校验broadcast队列是否已经为空,如果为空,则返回0,非空,则返回1 +* Return: +* 空返回0,非空返回1 +*/ +int wemq_thread_check_broadcast_mq_is_null (WemqThreadCtx * pThreadCtx) +{ + StMqInfo *p = wemq_thread_get_broadcast_mq (pThreadCtx); + if (p == NULL) + { + return 0; + } + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + usleep (1000); + if (*(p->mq->pHead) != *(p->mq->pTail)) + { + return 1; + } + return 0; +} + +int wemq_rr_msg_is_empty (stContextProxy * pContextProxy) +{ + + if (pContextProxy == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy is null"); + return 0; + } + + if (pContextProxy->stUnique.flag == 1) + { //有未回复的rr同步消息 + LOGRMB (RMB_LOG_DEBUG, "rr sync message is not response"); + return 1; + } + + struct timeval tv_now; + gettimeofday (&tv_now, NULL); + unsigned long ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + + int i; + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncOld. + get_array_size (&pContextProxy->pUniqueListForRRAsyncOld); i++) + { + if (pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag == 1) + { //有未回复的rr异步消息 + if (ulNowTime >= pContextProxy->ulLastPrintOldListIsEmpty + 1 * 1000) + { + LOGRMB (RMB_LOG_DEBUG, "rr async is message not response"); + pContextProxy->ulLastPrintOldListIsEmpty = ulNowTime; + } + return 1; + } + } + + LOGRMB (RMB_LOG_DEBUG, "rr msg is empty"); + return 0; +} + +int wemq_rr_all_msg_is_empty (stContextProxy * pContextProxy) +{ + + if (pContextProxy == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pContextProxy is null"); + return 0; + } + + if (pContextProxy->stUnique.flag == 1) + { //有未回复的rr同步消息 + LOGRMB (RMB_LOG_DEBUG, "rr sync message is not response"); + return 1; + } + + int i; + + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncNew. + get_array_size (&pContextProxy->pUniqueListForRRAsyncNew); i++) + { + + if (pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag == 1) + { //有未回复的rr异步消息 + LOGRMB (RMB_LOG_DEBUG, + "rr async message in new session is not response"); + return 1; + } + } + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncOld. + get_array_size (&pContextProxy->pUniqueListForRRAsyncOld); i++) + { + + if (pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag == 1) + { //有未回复的rr异步消息 + LOGRMB (RMB_LOG_DEBUG, + "rr async message in old session is not response"); + return 1; + } + } + + LOGRMB (RMB_LOG_DEBUG, "rr msg is empty"); + return 0; +} + +int32_t _wemq_thread_do_cmd_send_heart_beat (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * + pStWemqThreadMsg) +{ +// ASSERT(pStWemqThreadMsg->m_iCmd == THREAD_MSG_CMD_BEAT); + if (pThreadCtx == NULL || pStWemqThreadMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx or pStWemqThreadMsg is null"); + return -1; + } + + if (pStWemqThreadMsg->m_iCmd != THREAD_MSG_CMD_BEAT) + { + LOGRMB (RMB_LOG_ERROR, + "pStWemqThreadMsg->m_iCmd=%d, not THREAD_MSG_CMD_BEAT", + pStWemqThreadMsg->m_iCmd); + return -1; + } + + int iRet = -1; + int iTotalLen = pStWemqThreadMsg->m_iHeaderLen + 8; + + char *buf = pThreadCtx->m_pSendBuff; + ENCODE_INT (buf, iTotalLen); + ENCODE_INT (buf, pStWemqThreadMsg->m_iHeaderLen); + ENCODE_DWSTR_MEMCPY (buf, pStWemqThreadMsg->m_pHeader, + pStWemqThreadMsg->m_iHeaderLen); + //ENCODE_DWSTR_MEMCPY(buf, pStWemqThreadMsg->m_pBody, pStWemqThreadMsg->m_iBodyLen); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] |wemq_thread2accesss|Send:%s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pStWemqThreadMsg->m_pHeader); + + iRet = + _wemq_thread_do_send_sync (pThreadCtx, pThreadCtx->m_pSendBuff, iTotalLen, + pStWemqThreadMsg->m_iHeaderLen); + + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] _wemq_thread_do_send_sync error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return -2; + } + return 0; +} + +static int32_t _wemq_thread_send_heart_beat (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "pThreadCtx is null"); + //防止一直空转 + usleep (1000); + return -1; + } + +// if (pThreadCtx->m_iState == THREAD_STATE_INIT) +// { +// return 0; +// } + + if (pThreadCtx->m_iState != THREAD_STATE_OK) + { + return 0; + } + + if (pThreadCtx->m_iHeartBeatCount % HEART_BEAT_COUNT == 0) + { + pThreadCtx->m_iHeartBeatCount = 0; + gettimeofday (&pThreadCtx->stTimeNow, NULL); + + int time_inter = + pThreadCtx->stTimeNow.tv_sec - pThreadCtx->stTimeLast.tv_sec; + int time_inter_recv = + pThreadCtx->stTimeNow.tv_sec - pThreadCtx->stTimeLastRecv.tv_sec; + + //check heart beat time out + if (time_inter_recv >= pRmbStConfig->heartBeatTimeout) + { + //防止心跳超时日志多次打印 + pThreadCtx->stTimeLastRecv.tv_sec = pThreadCtx->stTimeNow.tv_sec; + LOGRMB (RMB_LOG_WARN, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] heart beat time out,current_times=%u!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_uiHeartBeatCurrent); + if (pThreadCtx->m_uiHeartBeatCurrent > 2) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] send two heart beat,but no receive!", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + pThreadCtx->m_uiHeartBeatCurrent = 0; + //add to black list + wemq_proxy_to_black_list (pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + + if (time_inter >= pRmbStConfig->heartBeatPeriod) + { + pThreadCtx->m_uiHeartBeatCurrent += 1; + int iRet = + _wemq_thread_do_cmd_send_heart_beat (pThreadCtx, + &pThreadCtx->m_stHeartBeat); + if (iRet == -2) + { + //_wemq_thread_del_fd(pThreadCtx); + //pThreadCtx->m_iSockFd = -1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + pThreadCtx->stTimeLast.tv_sec = pThreadCtx->stTimeNow.tv_sec; + pThreadCtx->stTimeLast.tv_usec = pThreadCtx->stTimeNow.tv_usec; + } + } + pThreadCtx->m_iHeartBeatCount++; + + return 0; +} + +static int32_t _wemq_thread_do_req (WemqThreadCtx * pThreadCtx, + StWemqThreadMsg * pStWemqThreadMsg) +{ + int iRet = -1; + switch (pStWemqThreadMsg->m_iCmd) + { + case THREAD_MSG_CMD_ADD_LISTEN: + { + iRet = + _wemq_thread_do_cmd_add_listen_msg (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_START: + { + iRet = _wemq_thread_do_cmd_start_msg (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread START CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + + return iRet; + } + case THREAD_MSG_CMD_SEND_MSG: + { + iRet = _wemq_thread_do_cmd_send_msg (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + + case THREAD_MSG_CMD_SEND_LOG: + { + iRet = _wemq_thread_do_cmd_send_log (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + + case THREAD_MSG_CMD_SEND_CLIENT_GOODBYE: + { + iRet = + _wemq_thread_do_cmd_client_goodbye_msg (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_SEND_REQUEST: + { + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] Thread REQ CMD THREAD_MSG_CMD_SEND_REQUEST", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + iRet = _wemq_thread_do_cmd_send_request (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_SEND_REQUEST_ASYNC: + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] Thread REQ CMD THREAD_MSG_CMD_SEND_REQUEST", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + iRet = + _wemq_thread_do_cmd_send_async_request (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_SEND_REPLY: + { + + iRet = _wemq_thread_do_cmd_send_reply (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return iRet; + } + case THREAD_MSG_CMD_SEND_MSG_ACK: + { + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] Do App ACK", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + + /* + iRet = _wemq_thread_do_cmd_send_msg_ack(pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg(pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + */ + iRet = _wemq_thread_do_cmd_send_msg_ack (pThreadCtx, pStWemqThreadMsg); + if (iRet == 0) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Thread REQ CMD ERROR %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + _wemq_thread_get_cmd (pStWemqThreadMsg->m_iCmd)); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + else + { + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + LOGRMB (RMB_LOG_ERROR, + "data processing ERR cause _wemq_thread_do_cmd_send_msg_ack failed."); + } + } + return iRet; + } + default: + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] do req error no such type req cmd %d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pStWemqThreadMsg->m_iCmd); + _wemq_thread_clear_thread_msg (pStWemqThreadMsg); + pThreadCtx->m_iWemqThreadMsgHandled = 1; + break; + } + return iRet; +} + +static int32_t _wemq_thread_do_last_failure_req (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx->m_iWemqThreadMsgHandled == 1) + { + return 0; + } + else + { + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] do last failure req!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + int iRet = + _wemq_thread_do_req (pThreadCtx, &pThreadCtx->m_stWemqThreadMsg); + if (iRet == -2) + { + _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + return iRet; + } + } + return 0; +} + +int do_ssl_connect (WemqThreadCtx * pThreadCtx) +{ + int err; + int sd; + struct sockaddr_in sa; + + if (NULL == pThreadCtx->sslCtx) + { + SSL_METHOD *meth; + + SSL_load_error_strings (); + SSLeay_add_ssl_algorithms (); + meth = TLSv1_2_client_method (); + pThreadCtx->sslCtx = SSL_CTX_new (meth); + } + + sd = socket (AF_INET, SOCK_STREAM, 0); + + memset (&sa, '\0', sizeof (sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr (pThreadCtx->m_cProxyIP); /* Server IP */ + sa.sin_port = htons (pThreadCtx->m_uiProxyPort); /* Server Port number */ + + err = connect (sd, (struct sockaddr *) &sa, sizeof (sa)); + if (0 != err) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u] tls tcp Connect Error, err=%d, errno=%d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort, err, errno); + close (sd); + return -1; + } + else + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u] tls tcp connect suc!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + } + + pThreadCtx->ssl = SSL_new (pThreadCtx->sslCtx); + SSL_set_fd (pThreadCtx->ssl, sd); + err = SSL_connect (pThreadCtx->ssl); + if (0 > err) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u] tls Connect Error, err=%d, errno=%d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort, err, errno); + wemq_tcp_close (sd, pThreadCtx->ssl); + pThreadCtx->ssl = NULL; + return -1; + } + + pThreadCtx->m_iSockFd = sd; + return 0; +} + +static int32_t _wemq_thread_do_connect (WemqThreadCtx * pThreadCtx) +{ + //随机sleep配置时间+0~9ms + struct timeval tv; + gettimeofday (&tv, NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + srand ((unsigned int) now_time); + int random_time = rand () % 10; + int retry = pRmbStConfig->iWemqTcpConnectRetryNum; + int sleep_time = pRmbStConfig->iWemqTcpConnectDelayTime * 1000; + int timeout = pRmbStConfig->iWemqTcpConnectTimeout + random_time; + + //memset(pThreadCtx->m_cProxyIP, 0, sizeof(pThreadCtx->m_cProxyIP)); + pThreadCtx->m_cProxyIP[0] = '\0'; + pThreadCtx->m_uiProxyPort = 0; + pThreadCtx->m_iLocalPort = 0; + + if (pThreadCtx->m_lRedirect == 0) + { + int iRet = 0; + do + { + iRet = + wemq_proxy_get_server (pThreadCtx->m_cProxyIP, + sizeof (pThreadCtx->m_cProxyIP), + &pThreadCtx->m_uiProxyPort); + if (iRet == 2) + { + LOGRMB (RMB_LOG_ERROR, "get proxy ip/port failed"); + sleep (1); + } + } + while (iRet == 2); + } + else + { + pThreadCtx->m_lRedirect = 0; + snprintf (pThreadCtx->m_cProxyIP, sizeof (pThreadCtx->m_cProxyIP), "%s", + pThreadCtx->m_cRedirectIP); + pThreadCtx->m_uiProxyPort = pThreadCtx->m_iRedirectPort; + } + + while (retry > 0) + { + if (0 != pRmbStConfig->tlsOnoff) + { + int err = do_ssl_connect (pThreadCtx); + if (0 != err) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [retry: %d|host:%s|port:%u] tls Connect Error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, retry, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + } + else + { + wemq_getsockename (pThreadCtx->m_iSockFd, NULL, 0, + &pThreadCtx->m_iLocalPort); + if (_wemq_thread_set_fd_nonblock (pThreadCtx, pThreadCtx->m_iSockFd) + != 0) + { + LOGRMB (RMB_LOG_ERROR, + "wemq thread set pThreadCtx->m_iSockFd=%d to nonblock failed", + pThreadCtx->m_iSockFd); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + } + else + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u|local_port:%d] tls connect to proxy, fd=%d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort, pThreadCtx->m_iLocalPort, + pThreadCtx->m_iSockFd); + //add fd to epoll + _wemq_thread_add_fd (pThreadCtx); + return 0; + } + } + } + else + { + int iSockFd = + wemq_tcp_connect (pThreadCtx->m_cProxyIP, + (uint16_t) pThreadCtx->m_uiProxyPort, timeout); + if (iSockFd > 0) + { + pThreadCtx->m_iSockFd = iSockFd; + wemq_getsockename (iSockFd, NULL, 0, &pThreadCtx->m_iLocalPort); + if (_wemq_thread_set_fd_nonblock (pThreadCtx, pThreadCtx->m_iSockFd) + != 0) + { + //exit(1); + LOGRMB (RMB_LOG_ERROR, + "wemq thread set pThreadCtx->m_iSockFd=%d to nonblock failed", + pThreadCtx->m_iSockFd); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + //return -1; + } + else + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u|local_port:%d] connect to proxy!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort, pThreadCtx->m_iLocalPort); + //add fd to epoll + _wemq_thread_add_fd (pThreadCtx); + return 0; + } + } + } + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] [retry: %d|host:%s|port:%u] Connect Error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, retry, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + retry--; + usleep (sleep_time); + if (retry == 0) + { + wemq_proxy_goodbye (pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [host:%s|port:%u] Connect Failed!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return -1; + } + + } + return -2; +} + +int32_t wemq_thread_state_init (WemqThreadCtx * pThreadCtx) +{ +// ASSERT(pThreadCtx); + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "wemq_thread_state_init: pThreadCtx is null"); + return -1; + } + pThreadCtx->m_iHeartBeatCount = 0; + pThreadCtx->m_uiHeartBeatCurrent = 0; + + gettimeofday (&pThreadCtx->stTimeNow, NULL); + gettimeofday (&pThreadCtx->stTimeLast, NULL); + gettimeofday (&pThreadCtx->stTimeLastRecv, NULL); + + //pThreadCtx->m_iThreadId = pThreadCtx->m_contextType; + pThreadCtx->m_iWemqThreadMsgHandled = 1; + pThreadCtx->m_threadID = pthread_self (); + +// pThreadCtx->m_lRedirect = false; + pThreadCtx->m_lRedirect = 0; + pThreadCtx->m_cRedirectIP[0] = '\0'; + pThreadCtx->m_iRedirectPort = 0; + + pThreadCtx->m_pRecvBuff = (char *) malloc (TCP_BUF_SIZE * sizeof (char)); + if (pThreadCtx->m_pRecvBuff == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] pThreadCtx->m_pRecvBuff malloc error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + memset (pThreadCtx->m_pRecvBuff, 0x00, + sizeof (TCP_BUF_SIZE * sizeof (char))); + + pThreadCtx->m_pSendBuff = (char *) malloc (TCP_BUF_SIZE * sizeof (char)); + if (pThreadCtx->m_pSendBuff == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] pThreadCtx->m_pSendBuff malloc error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + memset (pThreadCtx->m_pSendBuff, 0x00, TCP_BUF_SIZE * sizeof (char)); + + pThreadCtx->m_iEpollFd = epoll_create (1); + if (pThreadCtx->m_iEpollFd < 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] Create Epoll fd error:%d!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, errno); + return -3; + } + + pThreadCtx->m_ptEvents = + (struct epoll_event *) malloc (MAX_EVENT * sizeof (struct epoll_event)); + if (pThreadCtx->m_ptEvents == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] Create Malloc events error!", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + rmb_errno = RMB_ERROR_MALLOC_FAIL; + return -2; + } + + pThreadCtx->sslCtx = NULL; + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + pThreadCtx->m_iSockFdNew = -1; + pThreadCtx->sslNew = NULL; + pThreadCtx->m_iSockFdOld = -1; + pThreadCtx->sslOld = NULL; + pThreadCtx->m_iSockFd = -1; + + /* + pThreadCtx->m_stReqForHeartBeat.pid = CMD_HEART_BEAT; + pThreadCtx->m_stReqForHeartBeat.uiCount = 0; + */ + _wemq_thread_make_heart_beat_pkg (pThreadCtx); + _wemq_thread_make_hello_pkg (pThreadCtx); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_CONNECT); +} + +int32_t wemq_thread_state_connect (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_CONNECT); + + int ret = _wemq_thread_do_connect (pThreadCtx); + + if (ret == 0) + { + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_REGI); + } + else if (ret < 0) + { + /** + * 1. 使用default ip/port时,如果连接失败,则通知前端连接失败 + * 2. 如果从配置中心获取ip list失败或者获取到的ip list数量小于2个,则通知前端连接失败 + */ + if (pRmbStConfig->iWemqUseHttpCfg != 1 + || ((ret = rmb_get_wemq_proxy_list_num ()) <= 1)) + { + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->pubMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForPub == 0) + { + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->pubCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->pubMutex); + } + else if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->subMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForSub == 0) + { + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->subCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->subMutex); + } + } + + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + return ret; +} + +int32_t wemq_thread_state_regi (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_REGI); + int iRet = -1; + + iRet = _wemq_thread_do_cmd_send_msg_reg (pThreadCtx); + if (iRet == 0) + { + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->pubMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForPub == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForPub = 1; + pThreadCtx->m_ptProxyContext->iFlagForPublish = 1; + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->pubCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->pubMutex); + } + else if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->subMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForSub == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForSub = 1; + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->subCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->subMutex); + } + + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_OK); + } + else if (iRet < 0) + { + wemq_proxy_to_black_list (pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + return -1; +} + +int32_t wemq_thread_state_ok (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_OK); + + int iRet = -1; + + if ((pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + && (pThreadCtx->m_ptProxyContext->iFlagForPublish == 0)) + { + pThreadCtx->m_ptProxyContext->iFlagForPublish = 1; + } + + iRet = _wemq_thread_do_last_failure_req (pThreadCtx); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] CALL DO LAST FAILURE REQ ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + return iRet; + } + + //旧连接还在 + if (pThreadCtx->m_iSockFdOld >= 0) + { + + wemq_thread_do_deal_with_old_connect (pThreadCtx); + } + + int iMsgNum = 0; + int iRecv = 0; + iMsgNum = _wemq_thread_get_data_from_fifo (pThreadCtx); + if (iMsgNum > 0) + { + iRet = _wemq_thread_do_req (pThreadCtx, &pThreadCtx->m_stWemqThreadMsg); + if (iRet == -2) + { + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + } + + iRecv = _wemq_thread_do_recv_async (pThreadCtx, true); + if (iRecv > 0) + { + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] RECV %d bytes", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRecv); + iRet = _wemq_thread_on_message (pThreadCtx, true); + if (iRet == WEMQ_MESSAGE_RET_GOODBYE) + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV byebye cmd", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + wemq_proxy_goodbye (pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + else if (iRet == WEMQ_MESSAGE_RET_REDIRECT) + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] --> [redirect ip:%s|port:%d] RECV redirect cmd", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, + pThreadCtx->m_cRedirectIP, pThreadCtx->m_iRedirectPort); + //_wemq_thread_del_fd(pThreadCtx); + //close(pThreadCtx->m_iSockFd); + //pThreadCtx->m_iSockFd = -1; + //return _wemq_thread_state_trans(pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_BREAK); + wemq_proxy_goodbye (pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_CLOSE); //停止发消息; + } + else if (iRet == WEMQ_MESSAGE_RET_SERVERGOODBYE) //access端主动离线 + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV server goodbye cmd", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + //stContextProxy* pContextProxy = pThreadCtx->m_ptProxyContext; + + wemq_proxy_goodbye (pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + //wemq_thread_rr_msg_is_empty(pThreadCtx); + // _wemq_thread_del_fd(pThreadCtx); + // close(pThreadCtx->m_iSockFd); + // pThreadCtx->m_iSockFd = -1; + + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_CLOSE); //停止发消息; + } + else if (iRet == WEMQ_MESSAGE_RET_CLIENTGOODBYE) //client端主动离线,收到回包 + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV client goodbye cmd rsp", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + pContextProxy->iFlagForGoodBye = 1; + pthread_cond_signal (&pContextProxy->goodByeCond); + // + //pContextProxy->iFlagForRun = 0; //停止运行状态机 + return 0; + } + } + else + { + //LOGWEMQ(WEMQ_LOG_ERROR, "[%s],[TID:%d],ERROR RECV %d bytes\n", STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_iThreadId, iRecv); + if (iRecv == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu]Thread on Message ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + } + if (iRecv == -2) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] connect closed by peer", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + return 0; +} + +int32_t wemq_thread_state_close (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_CLOSE); + + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + int iRet = -1; + + int iMsgNum = 0; + int iRecv = 0; + /* + if (wemq_rr_msg_is_empty(pThreadCtx->m_ptProxyContext) == 0 && pThreadCtx->m_ptProxyContext->iFlagForEvent == 0) //rr同步和异步消息和单播的ack都已全部回来 + { + LOGRMB(RMB_LOG_INFO, "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV all rsp", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, + pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, + pThreadCtx->m_uiProxyPort); + //stContextProxy* pContextProxy = pThreadCtx->m_ptProxyContext; + + wemq_proxy_goodbye(pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + _wemq_thread_del_fd(pThreadCtx); + close(pThreadCtx->m_iSockFd); + pThreadCtx->m_iSockFd = -1; + return _wemq_thread_state_trans(pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_BREAK); //停止 + } + */ + + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pThreadCtx->m_iSockFdOld = pThreadCtx->m_iSockFd; + pThreadCtx->sslOld = pThreadCtx->ssl; + memcpy (pThreadCtx->m_cProxyIPOld, pThreadCtx->m_cProxyIP, + strlen (pThreadCtx->m_cProxyIP)); + pThreadCtx->m_uiProxyPortOld = pThreadCtx->m_uiProxyPort; + + Array pTempList = pContextProxy->pUniqueListForRRAsyncNew; + pContextProxy->pUniqueListForRRAsyncNew = + pContextProxy->pUniqueListForRRAsyncOld; + pContextProxy->pUniqueListForRRAsyncOld = pTempList; + + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + } + else + { + struct timeval tv_now; + gettimeofday (&tv_now, NULL); + + unsigned long ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + unsigned long ulLastTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + unsigned long timeout = 4 * 1000; + + while ((ulNowTime - ulLastTime) < timeout) + { + iMsgNum = _wemq_thread_get_data_from_fifo (pThreadCtx); + if (iMsgNum > 0) + { + iRet = + _wemq_thread_do_req (pThreadCtx, &pThreadCtx->m_stWemqThreadMsg); + } + else + if (pRmbStConfig->mqIsEmpty == MQ_INIT + || pRmbStConfig->mqIsEmpty == MQ_IS_EMPTY) + break; + gettimeofday (&tv_now, NULL); + ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + } + + } + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, THREAD_STATE_BREAK); //停止 + +} + +int32_t wemq_thread_state_break (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + ASSERT (pThreadCtx->m_iState == THREAD_STATE_BREAK); + //ASSERT(pThreadCtx->m_iSockFd == -1); + if (pThreadCtx->m_iSockFd >= 0) + { + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + } + + int ret = -1; + + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pThreadCtx->m_ptProxyContext->iFlagForPublish = 0; + } + + usleep (1000); + if ((ret = _wemq_thread_do_connect (pThreadCtx)) == 0) + { + pThreadCtx->m_uiHeartBeatCurrent = 0; + pThreadCtx->m_iHeartBeatCount = 0; + gettimeofday (&pThreadCtx->stTimeNow, NULL); + gettimeofday (&pThreadCtx->stTimeLast, NULL); + gettimeofday (&pThreadCtx->stTimeLastRecv, NULL); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_RECONNECT); + } + + if (wemq_proxy_ip_is_connected () == 1) + { //所有iplist已经遍历过一次 + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->pubMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForPub == 0) + { + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->pubCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->pubMutex); + } + else if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->subMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForSub == 0) + { + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->subCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->subMutex); + } + } + + return ret; +} + +int32_t wemq_thread_state_reconnect (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + //TODO RECONNECT; + //sleep(1); + struct timeval tv; + gettimeofday (&tv, NULL); + long now_time = tv.tv_sec * 1000000 + tv.tv_usec; + srand ((unsigned int) now_time); + //随机sleep 30~50ms ,usleep 单位是纳秒 + int sleep_time = rand () % 20 + 30; + usleep (sleep_time * 1000); + // hello msg + { + int iRet = -1; + + iRet = _wemq_thread_do_cmd_send_msg_reg (pThreadCtx); + if (iRet > 0) + { + return -1; + } + else if (iRet < 0) + { + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + + /** + * 程序首次起来时,如果选择的第一个ip连接失败而第二个ip连接成功且hello world指令发送成功,则应该通知前端连接成功 + */ + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_PUB) + { + if (pThreadCtx->m_ptProxyContext->iFlagForPublish == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForPublish = 1; + } + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->pubMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForPub == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForPub = 1; + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->pubCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->pubMutex); + } + else if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + { + pthread_mutex_lock (&pThreadCtx->m_ptProxyContext->subMutex); + if (pThreadCtx->m_ptProxyContext->iFlagForSub == 0) + { + pThreadCtx->m_ptProxyContext->iFlagForSub = 1; + pthread_cond_signal (&pThreadCtx->m_ptProxyContext->subCond); + } + pthread_mutex_unlock (&pThreadCtx->m_ptProxyContext->subMutex); + } + + int flag = 0; + //regist topic list + StWemqTopicProp *ptTopicProp = NULL; + if (pThreadCtx->m_ptTopicList != NULL) + { + ptTopicProp = pThreadCtx->m_ptTopicList->next; + } + WEMQJSON *jsonTopicList = json_object_new_array (); + char cBroadcastDcn[10] = "000"; + while (ptTopicProp != NULL) + { + flag = 1; + char cTopic[200]; + //char serviceOrEvent = (*(ptTopicProp->cServiceId + 3) == '0') ? 'e' : 's'; + char serviceOrEvent = (*(ptTopicProp->cServiceId + 3) == '0') ? 's' : 'e'; + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", + pRmbStConfig->cConsumerDcn, serviceOrEvent, + ptTopicProp->cServiceId, ptTopicProp->cScenario, + *(ptTopicProp->cServiceId + 3)); + json_object_array_add (jsonTopicList, json_object_new_string (cTopic)); + //自动监听广播topic + if (serviceOrEvent == 'e') + { + memset (cTopic, 0x00, sizeof (cTopic)); + snprintf (cTopic, sizeof (cTopic), "%s-%c-%s-%s-%c", cBroadcastDcn, + serviceOrEvent, ptTopicProp->cServiceId, + ptTopicProp->cScenario, *(ptTopicProp->cServiceId + 3)); + json_object_array_add (jsonTopicList, json_object_new_string (cTopic)); + } + ptTopicProp = ptTopicProp->next; + } + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_ADD_LISTEN; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonHeader failed"); + return -1; + } + + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (SUBSCRIBE_REQUEST)); + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + + WEMQJSON *jsonBody = json_object_new_object (); + if (jsonBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object for jsonBody failed"); + json_object_put (jsonHeader); + json_object_put (jsonTopicList); + return -1; + } + + json_object_object_add (jsonBody, MSG_BODY_TOPIC_LIST_JSON, jsonTopicList); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_get_string for header is null"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -2; + } + stThreadMsg.m_iHeaderLen = strlen (header_str); + + LOGRMB (RMB_LOG_DEBUG, + "[%s] [Type:%d] [TID:%lu] Gen thread msg header succ, len %d, %s", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, stThreadMsg.m_iHeaderLen, header_str); + stThreadMsg.m_pHeader = + (char *) malloc (stThreadMsg.m_iHeaderLen * sizeof (char) + 1); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for header failed"); + json_object_put (jsonBody); + json_object_put (jsonHeader); + return -1; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + json_object_put (jsonHeader); + + const char *body_str = json_object_get_string (jsonBody); + if (body_str == NULL) + { + json_object_put (jsonBody); + return -1; + } + + stThreadMsg.m_iBodyLen = strlen (body_str); + stThreadMsg.m_pBody = + (char *) malloc (stThreadMsg.m_iBodyLen * sizeof (char) + 1); + if (stThreadMsg.m_pBody == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for hello body failed"); + json_object_put (jsonBody); + return -1; + } + memcpy (stThreadMsg.m_pBody, body_str, stThreadMsg.m_iBodyLen); + stThreadMsg.m_pBody[stThreadMsg.m_iBodyLen] = '\0'; + + json_object_put (jsonBody); + + int iRet = _wemq_thread_do_cmd_add_listen_msg (pThreadCtx, &stThreadMsg); + if (iRet == -2) + { + free (stThreadMsg.m_pHeader); + free (stThreadMsg.m_pBody); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + iRet = _wemq_thread_do_recv_sync (pThreadCtx); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] Decode Wemq Header ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + StWeMQMSG *pWemqHeader = &pThreadCtx->m_stWeMQMSG; + jsonHeader = NULL; + WEMQJSON *jsonTmp = NULL; + char *usCmd; + char *msg; + int serRet = -1; + int seq = -1; + long time = 0; + + jsonHeader = json_tokener_parse (pWemqHeader->cStrJsonHeader); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] [LocalPort:%d] json_tokener_parse error: %s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, + pWemqHeader-> + cStrJsonHeader) return _wemq_thread_state_trans (pThreadCtx, + pThreadCtx-> + m_iState, + THREAD_STATE_BREAK); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_COMMAND_STR, &jsonTmp); + if (jsonTmp != NULL) + { + usCmd = json_object_get_string (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_CODE_INT, &jsonTmp); + if (jsonTmp != NULL) + { + serRet = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_SEQ_INT, &jsonTmp); + if (jsonTmp != NULL) + { + seq = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_MSG_STR, &jsonTmp); + if (jsonTmp != NULL) + { + msg = json_object_get_string (jsonTmp); + } + + json_object_put (jsonHeader); + + if ((serRet == 0) && strcmp (usCmd, SUBSCRIBE_RESPONSE) == 0) + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [msg:%s] [cmd:%s] register proxy success", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, msg, + usCmd); + + } + else + { + if (strcmp (usCmd, SUBSCRIBE_RESPONSE) == 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [msg:%s] [cmd:%s] [ret:%d] register proxy failed, iRet=%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, msg, + usCmd, serRet); + } + else + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] [Seq:%d] [msg:%s] [cmd:%s]register proxy failed, unknown cmd", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort, seq, msg, + usCmd); + } + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + //send start command + if (flag == 1) + { + StWemqThreadMsg stThreadMsg; + memset (&stThreadMsg, 0x00, sizeof (StWemqThreadMsg)); + stThreadMsg.m_iCmd = THREAD_MSG_CMD_START; + + WEMQJSON *jsonHeader = json_object_new_object (); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "json_object_new_object failed"); + return -2; + } + //add command + json_object_object_add (jsonHeader, MSG_HEAD_COMMAND_STR, + json_object_new_string (LISTEN_REQUEST)); + //add seq + json_object_object_add (jsonHeader, MSG_HEAD_SEQ_INT, + json_object_new_int (0)); + //add code + json_object_object_add (jsonHeader, MSG_HEAD_CODE_INT, + json_object_new_int (0)); + + const char *header_str = json_object_get_string (jsonHeader); + if (header_str == NULL) + { + LOGRMB (RMB_LOG_ERROR, "header is null"); + json_object_put (jsonHeader); + return -2; + } + + stThreadMsg.m_iHeaderLen = strlen (header_str); + LOGRMB (RMB_LOG_DEBUG, "Get thread msg header succ, len=%u, %s", + stThreadMsg.m_iHeaderLen, header_str) stThreadMsg.m_pHeader = + (char *) malloc ((stThreadMsg.m_iHeaderLen + 1) * sizeof (char)); + if (stThreadMsg.m_pHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, "malloc for stThreadMsg.m_pHeader failed"); + json_object_put (jsonHeader); + return -2; + } + memcpy (stThreadMsg.m_pHeader, header_str, stThreadMsg.m_iHeaderLen); + stThreadMsg.m_pHeader[stThreadMsg.m_iHeaderLen] = '\0'; + + json_object_put (jsonHeader); + + stThreadMsg.m_iBodyLen = 0; + stThreadMsg.m_pBody = NULL; + + int iRet = _wemq_thread_do_cmd_start_msg (pThreadCtx, &stThreadMsg); + if (iRet == -2) + { + _wemq_thread_clear_thread_msg (&stThreadMsg); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + iRet = _wemq_thread_do_recv_sync (pThreadCtx); + if (iRet != 0) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] Decode Wemq Header ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + StWeMQMSG *pWemqHeader = &pThreadCtx->m_stWeMQMSG; + jsonHeader = NULL; + WEMQJSON *jsonTmp = NULL; + char *usCmd; + char *msg; + int serRet = -1; + int seq = -1; + long time = 0; + + jsonHeader = json_tokener_parse (pWemqHeader->cStrJsonHeader); + if (jsonHeader == NULL) + { + LOGRMB (RMB_LOG_ERROR, + "[Type:%d] [TID:%lu] [LocalPort:%d] json_tokener_parse error:%s", + pThreadCtx->m_contextType, pThreadCtx->m_threadID, + pThreadCtx->m_iLocalPort, pWemqHeader->cStrJsonHeader); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + + json_object_object_get_ex (jsonHeader, MSG_HEAD_COMMAND_STR, &jsonTmp); + if (jsonTmp != NULL) + { + usCmd = json_object_get_string (jsonTmp); + } + + json_object_object_get_ex (jsonHeader, MSG_HEAD_CODE_INT, &jsonTmp); + if (jsonTmp != NULL) + { + serRet = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_SEQ_INT, &jsonTmp); + if (jsonTmp != NULL) + { + seq = json_object_get_int (jsonTmp); + } + json_object_object_get_ex (jsonHeader, MSG_HEAD_MSG_STR, &jsonTmp); + if (jsonTmp != NULL) + { + msg = json_object_get_string (jsonTmp); + } + + json_object_put (jsonHeader); + + if (serRet != 0 || (strcmp (usCmd, LISTEN_RESPONSE) != 0)) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [Seq:%d] [msg:%s] [CMD:%d] reconnect send start listen error:%d", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, seq, msg, + usCmd, serRet); + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_BREAK); + } + } + + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_OK); +} + +int32_t wemq_thread_state_destory (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + free (pThreadCtx->m_pRecvBuff); + free (pThreadCtx->m_pSendBuff); + free (pThreadCtx->m_ptEvents); + + if (pThreadCtx->m_iSockFd != -1) + { + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->m_iSockFd = -1; + pThreadCtx->ssl = NULL; + } + if (NULL != pThreadCtx->sslCtx) + { + SSL_CTX_free (pThreadCtx->sslCtx); + pThreadCtx->sslCtx = NULL; + } + return _wemq_thread_state_trans (pThreadCtx, pThreadCtx->m_iState, + THREAD_STATE_EXIT); +} + +void wemq_thread_clear_timeout_rr_async_request (WemqThreadCtx * pThreadCtx) +{ + if (pThreadCtx->m_contextType == RMB_CONTEXT_TYPE_SUB) + return; + stContextProxy *pContextProxy = pThreadCtx->m_ptProxyContext; + struct timeval tv_now; + gettimeofday (&tv_now, NULL); + unsigned long ulNowTime = tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000; + //int timeout = pRmbStConfig->rrAsyncTimeOut; + if (pThreadCtx->m_ptProxyContext->ulLastClearRRAysncMsgTime == 0) + { + pThreadCtx->m_ptProxyContext->ulLastClearRRAysncMsgTime = ulNowTime; + } + // 1s 清除一次 + if (ulNowTime >= + pThreadCtx->m_ptProxyContext->ulLastClearRRAysncMsgTime + 1 * 1000) + { + int i; + pthread_mutex_lock (&pContextProxy->rrMutex); + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncNew. + get_array_size (&pContextProxy->pUniqueListForRRAsyncNew); i++) + { + if (pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag == 1 + && ulNowTime >= + (pContextProxy->pUniqueListForRRAsyncNew.Data[i].timeStamp + + pContextProxy->pUniqueListForRRAsyncNew.Data[i].timeout)) + { //有超时的rr异步消息 + LOGRMB (RMB_LOG_WARN, + "rr async bizSeq:%s ,unique_id:%s time out, remove!", + pContextProxy->pUniqueListForRRAsyncNew.Data[i].biz_seq, + pContextProxy->pUniqueListForRRAsyncNew.Data[i].unique_id); + pContextProxy->pUniqueListForRRAsyncNew.Data[i].flag = 0; + } + } + for (i = 0; + i < + pContextProxy->pUniqueListForRRAsyncOld. + get_array_size (&pContextProxy->pUniqueListForRRAsyncOld); i++) + { + if (pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag == 1 + && ulNowTime >= + (pContextProxy->pUniqueListForRRAsyncOld.Data[i].timeStamp + + pContextProxy->pUniqueListForRRAsyncOld.Data[i].timeout)) + { //有超时的rr异步消息 + LOGRMB (RMB_LOG_WARN, + "rr old async bizSeq:%s ,unique_id:%s time out, remove!", + pContextProxy->pUniqueListForRRAsyncOld.Data[i].biz_seq, + pContextProxy->pUniqueListForRRAsyncOld.Data[i].unique_id); + pContextProxy->pUniqueListForRRAsyncOld.Data[i].flag = 0; + } + } + pthread_mutex_unlock (&pContextProxy->rrMutex); + pThreadCtx->m_ptProxyContext->ulLastClearRRAysncMsgTime = ulNowTime; + } +} + +void wemq_thread_do_deal_with_old_connect (WemqThreadCtx * pThreadCtx) +{ + ASSERT (pThreadCtx); + int iRecv = 0; + int iRet = -1; + if (pThreadCtx->m_iSockFdOld >= 0) + { + if (wemq_rr_msg_is_empty (pThreadCtx->m_ptProxyContext) == 0 && pThreadCtx->m_ptProxyContext->iFlagForEvent == 0) //rr同步和异步消息和单播的ack都已全部回来 + { + LOGRMB (RMB_LOG_INFO, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] RECV all rsp", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIPOld, pThreadCtx->m_uiProxyPortOld); + //stContextProxy* pContextProxy = pThreadCtx->m_ptProxyContext; + + wemq_proxy_goodbye (pThreadCtx->m_cProxyIPOld, + pThreadCtx->m_uiProxyPortOld); + _wemq_thread_del_old_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFdOld, pThreadCtx->sslOld); + pThreadCtx->m_iSockFdOld = -1; + pThreadCtx->sslOld = NULL; + return; + } + + iRecv = _wemq_thread_do_recv_async (pThreadCtx, false); + if (iRecv > 0) + { + LOGRMB (RMB_LOG_DEBUG, "[%s] [Type:%d] [TID:%lu] RECV %d bytes", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID, iRecv); + iRet = _wemq_thread_on_message (pThreadCtx, false); + + } + else + { + //LOGWEMQ(WEMQ_LOG_ERROR, "[%s],[TID:%d],ERROR RECV %d bytes\n", STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_iThreadId, iRecv); + if (iRecv == -1) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu]Thread on Message ERROR", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID); + } + if (iRecv == -2) + { + LOGRMB (RMB_LOG_ERROR, + "[%s] [Type:%d] [TID:%lu] [LocalPort:%d] [proxy ip:%s|port:%u] connect closed by peer", + STATE_MAP[pThreadCtx->m_iState], pThreadCtx->m_contextType, + pThreadCtx->m_threadID, pThreadCtx->m_iLocalPort, + pThreadCtx->m_cProxyIP, pThreadCtx->m_uiProxyPort); + wemq_proxy_goodbye (pThreadCtx->m_cProxyIPOld, + pThreadCtx->m_uiProxyPortOld); + _wemq_thread_del_old_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFdOld, pThreadCtx->sslOld); + pThreadCtx->m_iSockFdOld = -1; + pThreadCtx->sslOld = NULL; + + } + } + } +} + +int32_t wemq_thread_run (WemqThreadCtx * pThreadCtx) +{ +// ASSERT (pThreadCtx); + if (pThreadCtx == NULL) + { + LOGRMB (RMB_LOG_ERROR, "wemq_thread_run:pThreadCtx is null"); + return -1; + } + int iRet = 0; + int iRunFlag = 1; + int countDown = 0; + while (iRunFlag) +// while (pThreadCtx->m_ptProxyContext->iFlagForRun) + { + _wemq_thread_send_heart_beat (pThreadCtx); + switch (pThreadCtx->m_iState) + { + case THREAD_STATE_INIT: + { + _wemq_thread_check_init (pThreadCtx); + iRet = wemq_thread_state_init (pThreadCtx); + if (iRet < 0) + { + LOGRMB (RMB_LOG_ERROR, "wemq_thread_state_init failed,iRet=%d", + iRet); + return -1; + } + break; + } + case THREAD_STATE_CONNECT: + { + _wemq_thread_check_connect (pThreadCtx); + wemq_thread_state_connect (pThreadCtx); + break; + } + case THREAD_STATE_REGI: + { + _wemq_thread_check_regi (pThreadCtx); + wemq_thread_state_regi (pThreadCtx); + break; + } + case THREAD_STATE_OK: + { + _wemq_thread_check_ok (pThreadCtx); + wemq_thread_state_ok (pThreadCtx); + break; + } + case THREAD_STATE_CLOSE: + { + _wemq_thread_check_close (pThreadCtx); + wemq_thread_state_close (pThreadCtx); + break; + } + + case THREAD_STATE_BREAK: + { + _wemq_thread_check_break (pThreadCtx); + wemq_thread_state_break (pThreadCtx); + break; + } + case THREAD_STATE_RECONNECT: + { + _wemq_thread_check_reconnect (pThreadCtx); + wemq_thread_state_reconnect (pThreadCtx); + break; + } + case THREAD_STATE_DESTROY: + { + _wemq_thread_check_destory (pThreadCtx); + wemq_thread_state_destory (pThreadCtx); + break; + } + default: + iRunFlag = 0; + break; + } + wemq_thread_clear_timeout_rr_async_request (pThreadCtx); + if (pThreadCtx->m_ptProxyContext->iFlagForRun == 0) + { + if (wemq_thread_fifo_msg_is_empty (pThreadCtx) == 0 + && wemq_rr_all_msg_is_empty (pThreadCtx->m_ptProxyContext) == 0) + { + iRunFlag = 0; + } + else + { + GetRmbNowLongTime (); + unsigned long timeout = pRmbStConfig->ulExitTimeOut; //default:30s + //超过timeout直接退出 + if (pRmbStConfig->ulNowTtime >= + pThreadCtx->m_ptProxyContext->ulGoodByeTime + timeout) + { + iRunFlag = 0; + } + } + } + } + LOGRMB (RMB_LOG_INFO, "[%s] [Type:%d] [TID:%lu] THREAD EXIT!!!!", + STATE_MAP[pThreadCtx->m_iState], + pThreadCtx->m_contextType, pThreadCtx->m_threadID); + + _wemq_thread_del_fd (pThreadCtx); + wemq_tcp_close (pThreadCtx->m_iSockFd, pThreadCtx->ssl); + pThreadCtx->ssl = NULL; + pThreadCtx->m_iSockFd = -1; + + return 0; +} + +int32_t check_dyed_msg (StRmbMsg * rmbMsg) +{ + if (rmbMsg == NULL) + { + LOGRMB (RMB_LOG_ERROR, "rmbMsg is null"); + return -1; + } + if (strcmp (rmbMsg->isDyedMsg, "true") == 0) + { + return 1; + } + else + { + return 0; + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/src/wemq_topic_list.c b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_topic_list.c new file mode 100644 index 0000000000..7b3376e5e2 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/src/wemq_topic_list.c @@ -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. + +#include +#include "wemq_topic_list.h" + +static int print_wemq_topic (StWemqTopicProp * pArg) +{ + if (pArg == NULL) + { + printf ("pArg is null\n"); + return -1; + } + + if (pArg->flag == 0) + { + printf ("Topic:\n\tflag=%d\n\tserviceid=%s\n\tscenario=%s\n", pArg->flag, + pArg->cServiceId, pArg->cScenario); + } + else if (pArg->flag == 1) + { + printf ("Topic:\n\tflag=%d\n\ttopic=%s\n", pArg->flag, pArg->cTopic); + } + else + { + printf ("unknown flag:%d\n", pArg->flag); + } + + return 0; +} + +static int wemq_topic_list_iter (StWemqTopicList * ptTopicList, + WEMQ_DEC_FUNC func) +{ + StWemqTopicProp *tmp = ptTopicList->next; + while (tmp != NULL) + { + func (tmp); + tmp = tmp->next; + } + return 1; +} + +inline int32_t wemq_topic_list_is_empty (StWemqTopicList * ptTopicList) +{ + return (ptTopicList->next == NULL) ? 1 : 0; +} + +void wemq_topic_list_init (StWemqTopicList * ptTopicList) +{ + if (!wemq_topic_list_is_empty (ptTopicList)) + { + wemq_topic_list_clear (ptTopicList); + } + ptTopicList->next = NULL; + ptTopicList->tail = NULL; +} + +int wemq_topic_list_clear (StWemqTopicList * ptTopicList) +{ + if (ptTopicList == NULL) + { + return 1; + } + + StWemqTopicProp *ptTemp1 = ptTopicList->next; + StWemqTopicProp *ptTemp2 = ptTopicList->next; + while (ptTemp1 != NULL) + { + ptTemp1 = ptTemp1->next; + ptTemp2->next = NULL; + free (ptTemp2); + ptTemp2 = ptTemp1; + } + + return 1; +} + +int32_t wemq_topic_list_add_node (StWemqTopicList * ptTopicList, + StWemqTopicProp * ptTopicProp) +{ + if (ptTopicProp == NULL) + { + return -1; + } + + if (ptTopicList == NULL) + { + return -1; + } + + if (wemq_topic_list_find_node (ptTopicList, ptTopicProp, NULL) != 1) + { + if (ptTopicList->tail == NULL) + { + StWemqTopicProp *tmp = + (StWemqTopicProp *) malloc (sizeof (StWemqTopicProp)); + if (tmp == NULL) + { + printf ("malloc for StTopicProp failed!\n"); + return -2; + } + memset (tmp, 0, sizeof (StWemqTopicProp)); + if (ptTopicProp->flag == 0) + { + strncpy (tmp->cServiceId, ptTopicProp->cServiceId, + strlen (ptTopicProp->cServiceId)); + strncpy (tmp->cScenario, ptTopicProp->cScenario, + strlen (ptTopicProp->cScenario)); + } + else + { + strncpy (tmp->cTopic, ptTopicProp->cTopic, + strlen (ptTopicProp->cTopic)); + } + tmp->flag = ptTopicProp->flag; + tmp->next = NULL; + ptTopicList->next = tmp; + ptTopicList->tail = tmp; + } + else + { + StWemqTopicProp *tmp = + (StWemqTopicProp *) malloc (sizeof (StWemqTopicProp)); + if (tmp == NULL) + { + printf ("malloc for StTopicProp failed!\n"); + return -2; + } + memset (tmp, 0, sizeof (StWemqTopicProp)); + if (ptTopicProp->flag == 0) + { + strncpy (tmp->cServiceId, ptTopicProp->cServiceId, + strlen (ptTopicProp->cServiceId)); + strncpy (tmp->cScenario, ptTopicProp->cScenario, + strlen (ptTopicProp->cScenario)); + } + else + { + strncpy (tmp->cTopic, ptTopicProp->cTopic, + strlen (ptTopicProp->cTopic)); + } + tmp->flag = ptTopicProp->flag; + tmp->next = NULL; + ptTopicList->tail->next = tmp; + ptTopicList->tail = tmp; + } + return 1; + } + else + { + return 2; + } +} + +int32_t wemq_topic_list_find_node (StWemqTopicList * ptTopicList, + StWemqTopicProp * ptTopicProp, + StWemqTopicProp ** pos) +{ + if (ptTopicList == NULL || ptTopicProp == NULL) + { + return -1; + } + + StWemqTopicProp *tmp = ptTopicList->next; + while (tmp != NULL) + { + if (tmp->flag == 0) + { + if ((strncmp + (tmp->cServiceId, ptTopicProp->cServiceId, + strlen (tmp->cServiceId)) == 0) + && + (strncmp + (tmp->cScenario, ptTopicProp->cScenario, + strlen (tmp->cScenario)) == 0)) + { + if (pos != NULL) + *pos = tmp; + return 1; + } + } + else + { + if (strncmp (tmp->cTopic, ptTopicProp->cTopic, strlen (tmp->cTopic)) == + 0) + { + if (pos != NULL) + *pos = tmp; + + return 1; + } + } + + tmp = tmp->next; + } + return -1; +} + +int32_t wemq_topic_list_del_node (StWemqTopicList * ptTopicList, + StWemqTopicProp * ptTopicProp) +{ + StWemqTopicProp *pos = NULL; + if (wemq_topic_list_find_node (ptTopicList, ptTopicProp, &pos) != 1) + { + return -1; + } + + StWemqTopicProp *tmp1 = pos; + StWemqTopicProp *tmp2 = ptTopicList->next; + if (tmp2 == tmp1) + { + ptTopicList->next = tmp1->next; + free (tmp1); + return 1; + } + + while ((tmp2->next != tmp1) && (tmp2->next != NULL)) + { + tmp2 = tmp2->next; + } + tmp2->next = tmp1->next; + free (tmp1); + return 1; +} diff --git a/eventmesh-sdks/eventmesh-sdk-c/third_party/curl b/eventmesh-sdks/eventmesh-sdk-c/third_party/curl new file mode 160000 index 0000000000..d755a5f7c0 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/third_party/curl @@ -0,0 +1 @@ +Subproject commit d755a5f7c009dd63a61b2c745180d8ba937cbfeb diff --git a/eventmesh-sdks/eventmesh-sdk-c/third_party/json-c b/eventmesh-sdks/eventmesh-sdk-c/third_party/json-c new file mode 160000 index 0000000000..b4c371fa0c --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-c/third_party/json-c @@ -0,0 +1 @@ +Subproject commit b4c371fa0cbc4dcbaccc359ce9e957a22988fb34 diff --git a/eventmesh-sdks/eventmesh-sdk-java/build.gradle b/eventmesh-sdks/eventmesh-sdk-java/build.gradle index d62d6129c0..db15554031 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/build.gradle +++ b/eventmesh-sdks/eventmesh-sdk-java/build.gradle @@ -15,7 +15,7 @@ * limitations under the License. */ -def grpcVersion = '1.42.2' +def grpcVersion = '1.43.2' dependencies { api project(":eventmesh-common") @@ -32,6 +32,7 @@ dependencies { implementation "io.grpc:grpc-stub:${grpcVersion}" implementation "io.grpc:grpc-netty:${grpcVersion}" implementation "io.grpc:grpc-netty-shaded:${grpcVersion}" + implementation "io.cloudevents:cloudevents-protobuf" // protocol api "io.cloudevents:cloudevents-core" @@ -58,8 +59,6 @@ dependencies { testImplementation "org.assertj:assertj-core" - testImplementation "org.mockito:mockito-core" testImplementation "org.mockito:mockito-inline" - testImplementation "org.powermock:powermock-module-junit4" - testImplementation "org.powermock:powermock-api-mockito2" + testImplementation "org.mockito:mockito-junit-jupiter" } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/catalog/EventMeshCatalogClient.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/catalog/EventMeshCatalogClient.java index ab58f99053..ccaee18bb6 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/catalog/EventMeshCatalogClient.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/catalog/EventMeshCatalogClient.java @@ -66,9 +66,7 @@ public void init() { final QueryOperationsRequest request = QueryOperationsRequest.newBuilder() .setServiceName(clientConfig.getAppServerName()).build(); final QueryOperationsResponse response = catalogClient.queryOperations(request); - if (log.isInfoEnabled()) { - log.info("received response: {}", response); - } + log.info("received response: {}", response); final List operations = response.getOperationsList(); if (CollectionUtils.isEmpty(operations)) { diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/config/EventMeshGrpcClientConfig.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/config/EventMeshGrpcClientConfig.java index 461a6198b9..8d37802237 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/config/EventMeshGrpcClientConfig.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/config/EventMeshGrpcClientConfig.java @@ -57,6 +57,9 @@ public class EventMeshGrpcClientConfig { @Builder.Default private boolean useTls = false; + @Builder.Default + private long timeOut = 5_000; + @Override public String toString() { return "ClientConfig={ServerAddr=" @@ -78,6 +81,8 @@ public String toString() { + ",password=***" + ",useTls=" + useTls + + ",timeOut=" + + timeOut + "}"; } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumer.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumer.java index cf401c5b06..6ceefbe762 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumer.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumer.java @@ -21,35 +21,39 @@ import static java.util.stream.Collectors.toList; import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; -import org.apache.eventmesh.client.grpc.util.EventMeshClientUtil; +import org.apache.eventmesh.client.grpc.util.EventMeshCloudEventBuilder; import org.apache.eventmesh.client.tcp.common.EventMeshCommon; import org.apache.eventmesh.common.EventMeshThreadFactory; +import org.apache.eventmesh.common.enums.EventMeshDataContentType; import org.apache.eventmesh.common.enums.EventMeshProtocolType; +import org.apache.eventmesh.common.protocol.HeartbeatItem; 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.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.ConsumerServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.ConsumerServiceGrpc.ConsumerServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.ConsumerServiceGrpc.ConsumerServiceStub; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.HeartbeatServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.HeartbeatServiceGrpc.HeartbeatServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.common.ClientType; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.GrpcType; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.common.Response; 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.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.eventmesh.common.utils.JsonUtils; import org.apache.commons.collections4.MapUtils; -import org.apache.commons.lang3.StringUtils; -import java.util.HashSet; +import java.util.Collection; +import java.util.HashMap; 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.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import io.grpc.ManagedChannel; @@ -62,72 +66,67 @@ @Data public class EventMeshGrpcConsumer implements AutoCloseable { - private static final transient String SDK_STREAM_URL = "grpc_stream"; - private transient ManagedChannel channel; - private final transient EventMeshGrpcClientConfig clientConfig; + private static final String SDK_STREAM_URL = "grpc_stream"; + private ManagedChannel channel; + private final EventMeshGrpcClientConfig clientConfig; - private final transient Map subscriptionMap = new ConcurrentHashMap<>(); + private final Map subscriptionMap = new ConcurrentHashMap<>(); - private final transient ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor( - Runtime.getRuntime().availableProcessors(), + private final ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), new EventMeshThreadFactory("GRPCClientScheduler", true)); - private transient ConsumerServiceBlockingStub consumerClient; - private transient ConsumerServiceStub consumerAsyncClient; - private transient HeartbeatServiceBlockingStub heartbeatClient; + private ConsumerServiceBlockingStub consumerClient; + private ConsumerServiceStub consumerAsyncClient; + private HeartbeatServiceBlockingStub heartbeatClient; - private transient ReceiveMsgHook listener; - private transient SubStreamHandler subStreamHandler; + private ReceiveMsgHook listener; + private SubStreamHandler subStreamHandler; public EventMeshGrpcConsumer(final 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); - + this.channel = ManagedChannelBuilder.forAddress(clientConfig.getServerAddr(), clientConfig.getServerPort()).usePlaintext() + .build(); + this.consumerClient = ConsumerServiceGrpc.newBlockingStub(channel); + this.consumerAsyncClient = ConsumerServiceGrpc.newStub(channel); + this.heartbeatClient = HeartbeatServiceGrpc.newBlockingStub(channel); heartBeat(); } + /** + * Subscribes to an event at a specified URL(Webhook). + * + * @param subscriptionItems The list of subscription items. + * @param url The URL to subscribe to. + * @return A response containing information about the subscription result. + */ public Response subscribe(final List subscriptionItems, final String url) { - if (log.isInfoEnabled()) { - log.info("Create subscription: {} , url: {}", subscriptionItems, url); - } + log.info("Create subscription: {} , url: {}", subscriptionItems, url); - addSubscription(subscriptionItems, url); + addSubscription(subscriptionItems, url, GrpcType.WEBHOOK); - Subscription subscription = buildSubscription(subscriptionItems, url); - try { - Response response = consumerClient.subscribe(subscription); - if (log.isInfoEnabled()) { - log.info("Received response:{}", response); - } - return response; - } catch (Exception e) { - log.error("Error in subscribe.", e); - } - return null; + return subscribeWebhook(subscriptionItems, url); } + /** + * Subscribes to a streaming. + * + * @param subscriptionItems The list of subscription items for streaming. + */ public void subscribe(final List subscriptionItems) { - if (log.isInfoEnabled()) { - log.info("Create streaming subscription: {}", subscriptionItems); - } + log.info("Create streaming subscription: {}", subscriptionItems); if (listener == null) { log.error("Error in subscriber, no Event Listener is registered."); return; } - addSubscription(subscriptionItems, SDK_STREAM_URL); - - final Subscription subscription = buildSubscription(subscriptionItems, null); + addSubscription(subscriptionItems, SDK_STREAM_URL, GrpcType.STREAM); + CloudEvent subscription = EventMeshCloudEventBuilder.buildEventSubscription(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE, null, + subscriptionItems); synchronized (this) { if (subStreamHandler == null) { subStreamHandler = new SubStreamHandler<>(consumerAsyncClient, clientConfig, listener); @@ -137,34 +136,49 @@ public void subscribe(final List subscriptionItems) { subStreamHandler.sendSubscription(subscription); } - private void addSubscription(final List subscriptionItems, final String url) { + private Response subscribeWebhook(List subscriptionItems, String url) { + final CloudEvent subscription = EventMeshCloudEventBuilder.buildEventSubscription(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE, + url, subscriptionItems); + try { + CloudEvent response = consumerClient.subscribe(subscription); + log.info("Received response:{}", response); + return Response.builder() + .respCode(EventMeshCloudEventUtils.getResponseCode(response)) + .respMsg(EventMeshCloudEventUtils.getResponseMessage(response)) + .respTime(EventMeshCloudEventUtils.getResponseTime(response)) + .build(); + } catch (Exception e) { + log.error("Error in subscribe.", e); + } + return null; + } + + private void addSubscription(final List subscriptionItems, final String url, final GrpcType grpcType) { for (SubscriptionItem item : subscriptionItems) { - subscriptionMap.putIfAbsent(item.getTopic(), new SubscriptionInfo(item, url)); + subscriptionMap.putIfAbsent(item.getTopic(), new SubscriptionInfo(item, url, grpcType)); } } private void removeSubscription(final List subscriptionItems) { Objects.requireNonNull(subscriptionItems, "subscriptionItems can not be null"); - subscriptionItems.forEach(item -> { - subscriptionMap.remove(item.getTopic()); - }); + subscriptionItems.forEach(item -> subscriptionMap.remove(item.getTopic())); } public Response unsubscribe(final List subscriptionItems, final String url) { - if (log.isInfoEnabled()) { - log.info("Removing subscription: {}, url:{}", subscriptionItems, url); - } + log.info("Removing subscription: {}, url:{}", subscriptionItems, url); removeSubscription(subscriptionItems); - Subscription subscription = buildSubscription(subscriptionItems, url); - + final CloudEvent cloudEvent = EventMeshCloudEventBuilder.buildEventSubscription(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE, url, + subscriptionItems); try { - Response response = consumerClient.unsubscribe(subscription); - if (log.isInfoEnabled()) { - log.info("Received response:{}", response); - } - return response; + final CloudEvent response = consumerClient.unsubscribe(cloudEvent); + log.info("Received response:{}", response); + return Response.builder() + .respCode(EventMeshCloudEventUtils.getResponseCode(response)) + .respMsg(EventMeshCloudEventUtils.getResponseMessage(response)) + .respTime(EventMeshCloudEventUtils.getResponseTime(response)) + .build(); } catch (Exception e) { log.error("Error in unsubscribe.", e); } @@ -173,20 +187,21 @@ public Response unsubscribe(final List subscriptionItems, fina public Response unsubscribe(final List subscriptionItems) { Objects.requireNonNull(subscriptionItems, "subscriptionItems can not be null"); - if (log.isInfoEnabled()) { - log.info("Removing subscription stream: {}", subscriptionItems); - } + log.info("Removing subscription stream: {}", subscriptionItems); removeSubscription(subscriptionItems); - Subscription subscription = buildSubscription(subscriptionItems, null); + final CloudEvent cloudEvent = EventMeshCloudEventBuilder.buildEventSubscription(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE, null, + subscriptionItems); try { - Response response = consumerClient.unsubscribe(subscription); - - if (log.isInfoEnabled()) { - log.info("Received response:{}", response); - } + final CloudEvent response = consumerClient.unsubscribe(cloudEvent); + Response parsedResponse = Response.builder() + .respCode(EventMeshCloudEventUtils.getResponseCode(response)) + .respMsg(EventMeshCloudEventUtils.getResponseMessage(response)) + .respTime(EventMeshCloudEventUtils.getResponseTime(response)) + .build(); + log.info("Received response:{}", parsedResponse); // there is no stream subscriptions, stop the subscription stream handler synchronized (this) { @@ -194,56 +209,13 @@ public Response unsubscribe(final List subscriptionItems) { subStreamHandler.close(); } } - return response; + return parsedResponse; } catch (Exception e) { log.error("Error in unsubscribe.", e); } return null; } - public Subscription buildSubscription(final List subscriptionItems, final String url) { - Objects.requireNonNull(subscriptionItems, "subscriptionItems can not be null"); - - final Subscription.Builder builder = Subscription.newBuilder() - .setHeader(EventMeshClientUtil.buildHeader(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE)) - .setConsumerGroup(clientConfig.getConsumerGroup()); - - if (StringUtils.isNotEmpty(url)) { - builder.setUrl(url); - } - - Set subscriptionItemSet = new HashSet<>(); - subscriptionItemSet.addAll(subscriptionItems); - - for (SubscriptionItem subscriptionItem : subscriptionItemSet) { - Subscription.SubscriptionItem.SubscriptionMode mode; - if (SubscriptionMode.CLUSTERING == subscriptionItem.getMode()) { - mode = Subscription.SubscriptionItem.SubscriptionMode.CLUSTERING; - } else if (SubscriptionMode.BROADCASTING == subscriptionItem.getMode()) { - mode = Subscription.SubscriptionItem.SubscriptionMode.BROADCASTING; - } else { - mode = Subscription.SubscriptionItem.SubscriptionMode.UNRECOGNIZED; - } - - Subscription.SubscriptionItem.SubscriptionType type; - if (SubscriptionType.ASYNC == subscriptionItem.getType()) { - type = Subscription.SubscriptionItem.SubscriptionType.ASYNC; - } else if (SubscriptionType.SYNC == subscriptionItem.getType()) { - type = Subscription.SubscriptionItem.SubscriptionType.SYNC; - } else { - type = Subscription.SubscriptionItem.SubscriptionType.UNRECOGNIZED; - } - final Subscription.SubscriptionItem item = Subscription.SubscriptionItem.newBuilder() - .setTopic(subscriptionItem.getTopic()) - .setMode(mode) - .setType(type) - .build(); - builder.addSubscriptionItems(item); - } - - return builder.build(); - } - public synchronized void registerListener(final ReceiveMsgHook listener) { if (this.listener == null) { this.listener = listener; @@ -251,35 +223,32 @@ public synchronized void registerListener(final ReceiveMsgHook listener) { } private void heartBeat() { - final RequestHeader header = EventMeshClientUtil.buildHeader(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE); + final Map attributeValueMap = EventMeshCloudEventBuilder.buildCommonCloudEventAttributes(clientConfig, + EventMeshProtocolType.EVENT_MESH_MESSAGE); scheduler.scheduleAtFixedRate(() -> { if (MapUtils.isEmpty(subscriptionMap)) { return; } - - final Heartbeat.Builder heartbeatBuilder = Heartbeat.newBuilder() - .setHeader(header) - .setConsumerGroup(clientConfig.getConsumerGroup()) - .setClientType(Heartbeat.ClientType.SUB); - - subscriptionMap.forEach((topic, subscriptionInfo) -> { - Heartbeat.HeartbeatItem heartbeatItem = Heartbeat.HeartbeatItem - .newBuilder() - .setTopic(topic) - .setUrl(subscriptionInfo.getUrl()) - .build(); - heartbeatBuilder.addHeartbeatItems(heartbeatItem); - }); - - Heartbeat heartbeat = heartbeatBuilder.build(); + Map ext = new HashMap<>(attributeValueMap); + ext.put(ProtocolKey.CONSUMERGROUP, CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getConsumerGroup()).build()); + ext.put(ProtocolKey.CLIENT_TYPE, CloudEventAttributeValue.newBuilder().setCeInteger(ClientType.SUB.getType()).build()); + ext.put(ProtocolKey.DATA_CONTENT_TYPE, + CloudEventAttributeValue.newBuilder().setCeString(EventMeshDataContentType.JSON.getCode()).build()); + final CloudEvent.Builder heartbeatBuilder = CloudEvent.newBuilder().putAllAttributes(ext); + List heartbeatItems = subscriptionMap.entrySet().stream() + .map(entry -> HeartbeatItem.builder().topic(entry.getKey()).url(entry.getValue().getUrl()).build()).collect(toList()); + CloudEvent heartbeat = heartbeatBuilder.setTextData(JsonUtils.toJSONString(heartbeatItems)).build(); try { - final Response response = heartbeatClient.heartbeat(heartbeat); - if (log.isDebugEnabled()) { - log.debug("Grpc Consumer Heartbeat response: {}", response); - } - + CloudEvent cloudEventResp = heartbeatClient.heartbeat(heartbeat); + assert cloudEventResp != null; + Response response = Response.builder() + .respCode(EventMeshCloudEventUtils.getResponseCode(cloudEventResp)) + .respMsg(EventMeshCloudEventUtils.getResponseMessage(cloudEventResp)) + .respTime(EventMeshCloudEventUtils.getResponseTime(cloudEventResp)) + .build(); + log.debug("Grpc Consumer Heartbeat cloudEvent: {}", response); if (StatusCode.CLIENT_RESUBSCRIBE.getRetCode().equals(response.getRespCode())) { resubscribe(); } @@ -288,24 +257,34 @@ private void heartBeat() { } }, 10_000, EventMeshCommon.HEARTBEAT, TimeUnit.MILLISECONDS); - if (log.isInfoEnabled()) { - log.info("Grpc Consumer Heartbeat started."); - } + log.info("Grpc Consumer Heartbeat started."); } private void resubscribe() { if (subscriptionMap.isEmpty()) { return; } - - final Map> subscriptionGroup = - subscriptionMap.values().stream() - .collect(Collectors.groupingBy(SubscriptionInfo::getUrl, - mapping(SubscriptionInfo::getSubscriptionItem, toList()))); + final Collection values = subscriptionMap.values(); + final AtomicBoolean isStreamSub = new AtomicBoolean(false); + for (SubscriptionInfo info : values) { + if (info.grpcType == GrpcType.STREAM) { + isStreamSub.compareAndSet(false, true); + break; + } + } + final Map> subscriptionGroup = values.stream() + .collect(Collectors.groupingBy(SubscriptionInfo::getUrl, mapping(SubscriptionInfo::getSubscriptionItem, toList()))); subscriptionGroup.forEach((url, items) -> { - Subscription subscription = buildSubscription(items, url); - subStreamHandler.sendSubscription(subscription); + if (isStreamSub.get()) { + CloudEvent subscription = EventMeshCloudEventBuilder.buildEventSubscription(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE, + url, + items); + subStreamHandler.sendSubscription(subscription); + } else { + subscribeWebhook(items, url); + } + }); } @@ -328,10 +307,16 @@ private static class SubscriptionInfo { private transient SubscriptionItem subscriptionItem; private transient String url; + private GrpcType grpcType; - SubscriptionInfo(final SubscriptionItem subscriptionItem, final String url) { + SubscriptionInfo(final SubscriptionItem subscriptionItem, final String url, final GrpcType grpcType) { this.subscriptionItem = subscriptionItem; this.url = url; + this.grpcType = grpcType; + } + + public GrpcType getGrpcType() { + return grpcType; } public SubscriptionItem getSubscriptionItem() { diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/SubStreamHandler.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/SubStreamHandler.java index d639769c5e..d34a0c79b1 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/SubStreamHandler.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/consumer/SubStreamHandler.java @@ -18,13 +18,17 @@ 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 org.apache.eventmesh.client.grpc.util.EventMeshCloudEventBuilder; +import org.apache.eventmesh.common.enums.EventMeshDataContentType; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.ConsumerServiceGrpc.ConsumerServiceStub; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; + +import java.io.Serializable; import java.util.Optional; +import java.util.Set; import java.util.concurrent.CountDownLatch; import io.grpc.stub.StreamObserver; @@ -32,7 +36,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class SubStreamHandler extends Thread { +public class SubStreamHandler extends Thread implements Serializable { private final transient CountDownLatch latch = new CountDownLatch(1); @@ -40,9 +44,9 @@ public class SubStreamHandler extends Thread { private final transient EventMeshGrpcClientConfig clientConfig; - private transient StreamObserver sender; + private transient StreamObserver sender; - private final transient ReceiveMsgHook listener; + private final ReceiveMsgHook listener; public SubStreamHandler(final ConsumerServiceStub consumerAsyncClient, final EventMeshGrpcClientConfig clientConfig, final ReceiveMsgHook listener) { @@ -51,7 +55,7 @@ public SubStreamHandler(final ConsumerServiceStub consumerAsyncClient, final Eve this.listener = listener; } - public void sendSubscription(final Subscription subscription) { + public void sendSubscription(final CloudEvent subscription) { synchronized (this) { if (this.sender == null) { this.sender = consumerAsyncClient.subscribeStream(createReceiver()); @@ -60,39 +64,30 @@ public void sendSubscription(final Subscription subscription) { senderOnNext(subscription); } - private StreamObserver createReceiver() { - return new StreamObserver() { - @Override - public void onNext(final SimpleMessage message) { - T msg = EventMeshClientUtil.buildMessage(message, listener.getProtocolType()); + private StreamObserver createReceiver() { + return new StreamObserver() { - if (msg instanceof Map) { - if (log.isInfoEnabled()) { - log.info("Received message from Server:{}", message); - } + @Override + public void onNext(final CloudEvent message) { + T msg = EventMeshCloudEventBuilder.buildMessageFromEventMeshCloudEvent(message, listener.getProtocolType()); + if (msg instanceof Set) { + log.info("Received message from Server:{}", message); } else { - if (log.isInfoEnabled()) { - log.info("Received message from Server.|seq={}|uniqueId={}|", message.getSeqNum(), - message.getUniqueId()); - } - Subscription streamReply = null; + log.info("Received message from Server.|seq={}|uniqueId={}|", + EventMeshCloudEventUtils.getSeqNum(message), EventMeshCloudEventUtils.getUniqueId(message)); + CloudEvent streamReply = null; try { Optional reply = listener.handle(msg); if (reply.isPresent()) { streamReply = buildReplyMessage(message, reply.get()); } } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("Error in handling reply message.|seq={}|uniqueId={}|", - message.getSeqNum(), message.getUniqueId(), e); - } + log.error("Error in handling reply message.|seq={}|uniqueId={}|", + EventMeshCloudEventUtils.getSeqNum(message), EventMeshCloudEventUtils.getUniqueId(message), e); } if (streamReply != null) { - if (log.isInfoEnabled()) { - log.info("Sending reply message to Server.|seq={}|uniqueId={}|", - streamReply.getReply().getSeqNum(), - streamReply.getReply().getUniqueId()); - } + log.info("Sending reply message to Server.|seq={}|uniqueId={}|", + EventMeshCloudEventUtils.getSeqNum(streamReply), EventMeshCloudEventUtils.getUniqueId(streamReply)); senderOnNext(streamReply); } } @@ -100,40 +95,27 @@ public void onNext(final SimpleMessage message) { @Override public void onError(final Throwable t) { - if (log.isErrorEnabled()) { - log.error("Received Server side error", t); - } - close(); + log.error("Received Server side error", t); } @Override public void onCompleted() { - if (log.isInfoEnabled()) { - log.info("Finished receiving messages from server."); - } + log.info("Finished receiving messages from server."); close(); } }; } - private Subscription buildReplyMessage(final SimpleMessage reqMessage, final T replyMessage) { - final SimpleMessage simpleMessage = EventMeshClientUtil.buildSimpleMessage(replyMessage, + private CloudEvent buildReplyMessage(final CloudEvent reqMessage, final T replyMessage) { + final CloudEvent cloudEvent = EventMeshCloudEventBuilder.buildEventMeshCloudEvent(replyMessage, clientConfig, listener.getProtocolType()); - final 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()) + return CloudEvent.newBuilder(cloudEvent).putAllAttributes(reqMessage.getAttributesMap()).putAllAttributes(cloudEvent.getAttributesMap()) + .putAttributes(ProtocolKey.DATA_CONTENT_TYPE, + CloudEventAttributeValue.newBuilder().setCeString(EventMeshDataContentType.JSON.getCode()).build()) + // Indicate that it is a subscription response + .putAttributes(ProtocolKey.SUB_MESSAGE_TYPE, CloudEventAttributeValue.newBuilder().setCeString(ProtocolKey.SUB_REPLY_MESSAGE).build()) .build(); - - return Subscription.newBuilder() - .setHeader(simpleMessage.getHeader()) - .setReply(reply).build(); } @Override @@ -142,6 +124,7 @@ public void run() { latch.await(); } catch (InterruptedException e) { log.error("SubStreamHandler Thread interrupted", e); + Thread.currentThread().interrupt(); } } @@ -152,12 +135,10 @@ public void close() { latch.countDown(); - if (log.isInfoEnabled()) { - log.info("SubStreamHandler closed."); - } + log.info("SubStreamHandler closed."); } - private void senderOnNext(final Subscription subscription) { + private void senderOnNext(final CloudEvent subscription) { try { synchronized (sender) { sender.onNext(subscription); diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/exception/ProtocolNotSupportException.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/exception/ProtocolNotSupportException.java new file mode 100644 index 0000000000..ef89340a84 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/exception/ProtocolNotSupportException.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.grpc.exception; + +public class ProtocolNotSupportException extends RuntimeException { + + /** + * Constructs a new runtime exception with {@code null} as its detail message. The cause is not initialized, and may subsequently be initialized + * by a call to {@link #initCause}. + */ + public ProtocolNotSupportException() { + super(); + } + + /** + * Constructs a new runtime exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + public ProtocolNotSupportException(String message) { + super(message); + } + + /** + * Constructs a new runtime exception with the specified detail message and cause.

Note that the detail message associated with {@code cause} + * is not automatically incorporated in this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public ProtocolNotSupportException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of + * cause). This constructor is useful for runtime exceptions + * that are little more than wrappers for other throwables. + * + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and + * indicates that the cause is nonexistent or unknown.) + * @since 1.4 + */ + public ProtocolNotSupportException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new runtime exception with the specified detail message, cause, suppression enabled or disabled, and writable stack trace enabled + * or disabled. + * + * @param message the detail message. + * @param cause the cause. (A {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) + * @param enableSuppression whether or not suppression is enabled or disabled + * @param writableStackTrace whether or not the stack trace should be writable + * @since 1.7 + */ + protected ProtocolNotSupportException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducer.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducer.java index 57b8c88053..3dc1288012 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducer.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducer.java @@ -18,32 +18,23 @@ 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.common.Constants; +import org.apache.eventmesh.client.grpc.util.EventMeshCloudEventBuilder; import org.apache.eventmesh.common.enums.EventMeshProtocolType; -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 org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.Response; +import org.apache.eventmesh.common.utils.LogUtil; import org.apache.commons.collections4.CollectionUtils; import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - - -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; import lombok.extern.slf4j.Slf4j; @Slf4j -public class CloudEventProducer implements GrpcProducer { +public class CloudEventProducer implements GrpcProducer { private static final EventMeshProtocolType PROTOCOL_TYPE = EventMeshProtocolType.CLOUD_EVENTS; @@ -58,106 +49,60 @@ public CloudEventProducer(final EventMeshGrpcClientConfig clientConfig, } @Override - public Response publish(final List events) { - if (log.isInfoEnabled()) { - log.info("BatchPublish message, batch size={}", events.size()); - } + public Response publish(final List events) { + log.info("BatchPublish message, batch size={}", events.size()); if (CollectionUtils.isEmpty(events)) { return null; } - final List enhancedEvents = events.stream() - .map(event -> enhanceCloudEvent(event, null)) - .collect(Collectors.toList()); - - final BatchMessage enhancedMessage = EventMeshClientUtil.buildBatchMessages(enhancedEvents, clientConfig, PROTOCOL_TYPE); + final CloudEventBatch cloudEventBatch = EventMeshCloudEventBuilder.buildEventMeshCloudEventBatch(events, clientConfig, PROTOCOL_TYPE); try { - final Response response = publisherClient.batchPublish(enhancedMessage); - if (log.isInfoEnabled()) { - log.info("Received response:{}", response.toString()); - } - return response; + final CloudEvent response = publisherClient.batchPublish(cloudEventBatch); + Response parsedResponse = Response.builder() + .respCode(EventMeshCloudEventUtils.getResponseCode(response)) + .respMsg(EventMeshCloudEventUtils.getResponseMessage(response)) + .respTime(EventMeshCloudEventUtils.getResponseTime(response)) + .build(); + + log.info("Received response:{}", parsedResponse); + return parsedResponse; } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("Error in BatchPublish message {}", events, e); - } + log.error("Error in BatchPublish message {}", events, e); } return null; } @Override - public Response publish(final CloudEvent cloudEvent) { - if (log.isInfoEnabled()) { - log.info("Publish message: {}", cloudEvent.toString()); - } - final CloudEvent enhanceEvent = enhanceCloudEvent(cloudEvent, null); - - final SimpleMessage enhancedMessage = EventMeshClientUtil.buildSimpleMessage(enhanceEvent, clientConfig, PROTOCOL_TYPE); - + public Response publish(final io.cloudevents.CloudEvent cloudEvent) { + LogUtil.info(log, "Publish message: {}", cloudEvent::toString); + CloudEvent enhancedMessage = EventMeshCloudEventBuilder.buildEventMeshCloudEvent(cloudEvent, clientConfig, PROTOCOL_TYPE); try { - final Response response = publisherClient.publish(enhancedMessage); - if (log.isInfoEnabled()) { - log.info("Received response:{} ", response.toString()); - } - return response; + final CloudEvent response = publisherClient.publish(enhancedMessage); + Response parsedResponse = Response.builder() + .respCode(EventMeshCloudEventUtils.getResponseCode(response)) + .respMsg(EventMeshCloudEventUtils.getResponseMessage(response)) + .respTime(EventMeshCloudEventUtils.getResponseTime(response)) + .build(); + log.info("Received response:{} ", parsedResponse); + return parsedResponse; } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("Error in publishing message {}", cloudEvent, e); - } + log.error("Error in publishing message {}", cloudEvent, e); } return null; } @Override - public CloudEvent requestReply(final CloudEvent cloudEvent, final long timeout) { - if (log.isInfoEnabled()) { - log.info("RequestReply message {}", cloudEvent); - } - final CloudEvent enhanceEvent = enhanceCloudEvent(cloudEvent, String.valueOf(timeout)); - - final SimpleMessage enhancedMessage = EventMeshClientUtil.buildSimpleMessage(enhanceEvent, clientConfig, - PROTOCOL_TYPE); + public io.cloudevents.CloudEvent requestReply(final io.cloudevents.CloudEvent cloudEvent, final long timeout) { + log.info("RequestReply message {}", cloudEvent); + final CloudEvent enhancedMessage = EventMeshCloudEventBuilder.buildEventMeshCloudEvent(cloudEvent, clientConfig, PROTOCOL_TYPE); try { - final SimpleMessage reply = publisherClient.requestReply(enhancedMessage); - if (log.isInfoEnabled()) { - log.info("Received reply message:{}", reply); - } - - final Object msg = EventMeshClientUtil.buildMessage(reply, PROTOCOL_TYPE); - if (msg instanceof CloudEvent) { - return (CloudEvent) msg; - } else { - return null; - } + final CloudEvent reply = publisherClient.requestReply(enhancedMessage); + log.info("Received reply message:{}", reply); + return EventMeshCloudEventBuilder.buildMessageFromEventMeshCloudEvent(reply, PROTOCOL_TYPE); } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("Error in RequestReply message {}", cloudEvent, e); - } + log.error("Error in RequestReply message {}", cloudEvent, e); } return null; } - - private CloudEvent enhanceCloudEvent(final CloudEvent cloudEvent, final String timeout) { - final CloudEventBuilder builder = CloudEventBuilder.from(cloudEvent) - .withExtension(ProtocolKey.ENV, clientConfig.getEnv()) - .withExtension(ProtocolKey.IDC, clientConfig.getIdc()) - .withExtension(ProtocolKey.IP, Objects.requireNonNull(IPUtils.getLocalAddress())) - .withExtension(ProtocolKey.PID, Long.toString(ThreadUtils.getPID())) - .withExtension(ProtocolKey.SYS, clientConfig.getSys()) - .withExtension(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) - .withExtension(ProtocolKey.PROTOCOL_TYPE, PROTOCOL_TYPE.protocolTypeName()) - .withExtension(ProtocolKey.PROTOCOL_DESC, Constants.PROTOCOL_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(); - } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducer.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducer.java index b9f82af514..5003ed9489 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducer.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducer.java @@ -20,9 +20,10 @@ import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; import org.apache.eventmesh.client.tcp.common.EventMeshCommon; import org.apache.eventmesh.common.EventMeshMessage; -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.cloudevents.PublisherServiceGrpc; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.common.Response; +import org.apache.eventmesh.common.utils.LogUtil; import org.apache.commons.collections4.CollectionUtils; @@ -47,9 +48,9 @@ public class EventMeshGrpcProducer implements AutoCloseable { private PublisherServiceBlockingStub publisherClient; - private CloudEventProducer cloudEventProducer; + private CloudEventProducer cloudEventProducer; - private EventMeshMessageProducer eventMeshMessageProducer; + private EventMeshMessageProducer eventMeshMessageProducer; public EventMeshGrpcProducer(EventMeshGrpcClientConfig clientConfig) { this.clientConfig = clientConfig; @@ -60,9 +61,7 @@ public EventMeshGrpcProducer(EventMeshGrpcClientConfig clientConfig) { } public Response publish(T message) { - if (log.isInfoEnabled()) { - log.info("Publish message " + message.toString()); - } + LogUtil.info(log, "Publish message: {}", message::toString); if (message instanceof CloudEvent) { return cloudEventProducer.publish((CloudEvent) message); } else if (message instanceof EventMeshMessage) { @@ -74,9 +73,7 @@ public Response publish(T message) { @SuppressWarnings("unchecked") public Response publish(List messageList) { - if (log.isInfoEnabled()) { - log.info("BatchPublish message :{}", messageList); - } + log.info("BatchPublish message: {}", messageList); if (CollectionUtils.isEmpty(messageList)) { return null; diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshMessageProducer.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshMessageProducer.java index a298b08387..229fb29715 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshMessageProducer.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/EventMeshMessageProducer.java @@ -18,13 +18,14 @@ 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.grpc.util.EventMeshCloudEventBuilder; import org.apache.eventmesh.common.EventMeshMessage; import org.apache.eventmesh.common.enums.EventMeshProtocolType; -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.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.Response; import org.apache.commons.collections4.CollectionUtils; @@ -54,16 +55,17 @@ public Response publish(EventMeshMessage message) { return null; } - if (log.isDebugEnabled()) { - log.info("Publish message: {}", message.toString()); - } - SimpleMessage simpleMessage = EventMeshClientUtil.buildSimpleMessage(message, clientConfig, PROTOCOL_TYPE); + log.debug("Publish message: {}", message); + CloudEvent cloudEvent = EventMeshCloudEventBuilder.buildEventMeshCloudEvent(message, clientConfig, PROTOCOL_TYPE); try { - Response response = publisherClient.publish(simpleMessage); - if (log.isInfoEnabled()) { - log.info("Received response:{}", response); - } - return response; + CloudEvent response = publisherClient.publish(cloudEvent); + Response parsedResponse = Response.builder() + .respCode(EventMeshCloudEventUtils.getResponseCode(response)) + .respMsg(EventMeshCloudEventUtils.getResponseMessage(response)) + .respTime(EventMeshCloudEventUtils.getResponseTime(response)) + .build(); + log.info("Received response:{}", parsedResponse); + return parsedResponse; } catch (Exception e) { log.error("Error in publishing message {}", message, e); } @@ -76,46 +78,33 @@ public Response publish(List messages) { if (CollectionUtils.isEmpty(messages)) { return null; } - BatchMessage batchMessage = EventMeshClientUtil.buildBatchMessages(messages, clientConfig, PROTOCOL_TYPE); + CloudEventBatch cloudEventBatch = EventMeshCloudEventBuilder.buildEventMeshCloudEventBatch(messages, clientConfig, PROTOCOL_TYPE); try { - Response response = publisherClient.batchPublish(batchMessage); - if (log.isInfoEnabled()) { - log.info("Received response:{}", response); - } - return response; + CloudEvent response = publisherClient.batchPublish(cloudEventBatch); + Response parsedResponse = Response.builder() + .respCode(EventMeshCloudEventUtils.getResponseCode(response)) + .respMsg(EventMeshCloudEventUtils.getResponseMessage(response)) + .respTime(EventMeshCloudEventUtils.getResponseTime(response)) + .build(); + log.info("Received response:{}", parsedResponse); + return parsedResponse; } catch (Exception e) { - if (log.isErrorEnabled()) { - log.error("Error in BatchPublish message {}", messages, e); - } + log.error("Error in BatchPublish message {}", messages, e); } return null; } @Override public EventMeshMessage requestReply(EventMeshMessage message, long timeout) { - if (log.isInfoEnabled()) { - log.info("RequestReply message:{}", message); - } + log.info("RequestReply message:{}", message); - SimpleMessage simpleMessage = EventMeshClientUtil.buildSimpleMessage(message, clientConfig, PROTOCOL_TYPE); + final CloudEvent cloudEvent = EventMeshCloudEventBuilder.buildEventMeshCloudEvent(message, clientConfig, PROTOCOL_TYPE); try { - SimpleMessage reply = publisherClient.withDeadlineAfter(timeout, TimeUnit.MILLISECONDS) - .requestReply(simpleMessage); - if (log.isInfoEnabled()) { - log.info("Received reply message:{}", reply); - } - - final Object msg = EventMeshClientUtil.buildMessage(reply, PROTOCOL_TYPE); - if (msg instanceof EventMeshMessage) { - return (EventMeshMessage) msg; - } else { - return null; - } + final CloudEvent reply = publisherClient.withDeadlineAfter(timeout, TimeUnit.MILLISECONDS).requestReply(cloudEvent); + log.info("Received reply message:{}", reply); + return EventMeshCloudEventBuilder.buildMessageFromEventMeshCloudEvent(reply, PROTOCOL_TYPE); } catch (Exception e) { - e.printStackTrace(); - if (log.isErrorEnabled()) { - log.error("Error in RequestReply message {}", message, e); - } + log.error("Error in RequestReply message {}", message, e); } return null; } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/GrpcProducer.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/GrpcProducer.java index a209d1e85b..4c63485b44 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/GrpcProducer.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/producer/GrpcProducer.java @@ -17,7 +17,7 @@ package org.apache.eventmesh.client.grpc.producer; -import org.apache.eventmesh.common.protocol.grpc.protos.Response; +import org.apache.eventmesh.common.protocol.grpc.common.Response; import java.util.List; diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtil.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtil.java deleted file mode 100644 index f39fcb3e80..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtil.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.client.grpc.util; - -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.enums.EventMeshProtocolType; -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.Objects; -import java.util.Optional; - -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 { - - public static RequestHeader buildHeader(EventMeshGrpcClientConfig clientConfig, EventMeshProtocolType 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.protocolTypeName()) - .setProtocolDesc(Constants.PROTOCOL_GRPC) - // default CloudEvents version is V1 - .setProtocolVersion(SpecVersion.V1.toString()) - .build(); - } - - @SuppressWarnings("unchecked") - public static T buildMessage(final SimpleMessage message, final EventMeshProtocolType protocolType) { - - if (null == message) { - return null; - } - final String seq = message.getSeqNum(); - final String uniqueId = message.getUniqueId(); - final String content = message.getContent(); - - // This is GRPC response message - if (StringUtils.isAllEmpty(message.getSeqNum(), message.getUniqueId())) { - return (T) JsonUtils.parseTypeReferenceObject(content, - new TypeReference>() { - }); - } - if (null == protocolType) { - return null; - } - - switch (protocolType) { - case CLOUD_EVENTS: - return (T) switchSimpleMessage2CloudEvent(message, content); - case EVENT_MESH_MESSAGE: - return (T) switchSimpleMessage2EventMeshMessage(message, seq, uniqueId, content); - case OPEN_MESSAGE: - default: - return null; - } - } - - private static EventMeshMessage switchSimpleMessage2EventMeshMessage(SimpleMessage message, String seq, String uniqueId, String content) { - return EventMeshMessage.builder() - .content(content) - .topic(message.getTopic()) - .bizSeqNo(seq) - .uniqueId(uniqueId) - .prop(message.getPropertiesMap()) - .build(); - } - - private static CloudEvent switchSimpleMessage2CloudEvent(SimpleMessage message, String content) { - final String contentType = message.getPropertiesOrDefault(ProtocolKey.CONTENT_TYPE, JsonFormat.CONTENT_TYPE); - final CloudEvent cloudEvent = Objects.requireNonNull(EventFormatProvider.getInstance().resolveFormat(contentType)) - .deserialize(content.getBytes(Constants.DEFAULT_CHARSET)); - - final 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 cloudEventBuilder.build(); - } - - public static SimpleMessage buildSimpleMessage(final T message, final EventMeshGrpcClientConfig clientConfig, - final EventMeshProtocolType protocolType) { - - switch (protocolType) { - case CLOUD_EVENTS: - return switchCloudEvents2SimpleMessage((CloudEvent) message, clientConfig, protocolType); - case EVENT_MESH_MESSAGE: - return switchEventMessage2SimpleMessage((EventMeshMessage) message, clientConfig, protocolType); - case OPEN_MESSAGE: - default: - return null; - } - } - - private static SimpleMessage switchEventMessage2SimpleMessage(EventMeshMessage message, EventMeshGrpcClientConfig clientConfig, - EventMeshProtocolType protocolType) { - final EventMeshMessage eventMeshMessage = message; - - final String ttl = eventMeshMessage.getProp(Constants.EVENTMESH_MESSAGE_CONST_TTL) == null - ? Constants.DEFAULT_EVENTMESH_MESSAGE_TTL : eventMeshMessage.getProp(Constants.EVENTMESH_MESSAGE_CONST_TTL); - final Map props = eventMeshMessage.getProp() == null ? new HashMap<>() : eventMeshMessage.getProp(); - final String seqNum = eventMeshMessage.getBizSeqNo() == null ? RandomStringUtils.generateNum(30) : eventMeshMessage.getBizSeqNo(); - final 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(); - } - - private static SimpleMessage switchCloudEvents2SimpleMessage(CloudEvent message, EventMeshGrpcClientConfig clientConfig, - EventMeshProtocolType protocolType) { - final CloudEvent cloudEvent = message; - final String contentType = StringUtils.isEmpty(cloudEvent.getDataContentType()) - ? Constants.CONTENT_TYPE_CLOUDEVENTS_JSON - : cloudEvent.getDataContentType(); - final byte[] bodyByte = Objects.requireNonNull(EventFormatProvider.getInstance().resolveFormat(contentType)) - .serialize(cloudEvent); - final String content = new String(bodyByte, StandardCharsets.UTF_8); - final String ttl = cloudEvent.getExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL) == null - ? Constants.DEFAULT_EVENTMESH_MESSAGE_TTL - : Objects.requireNonNull(cloudEvent.getExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL)).toString(); - - final String seqNum = cloudEvent.getExtension(ProtocolKey.SEQ_NUM) == null - ? RandomStringUtils.generateNum(30) - : Objects.requireNonNull(cloudEvent.getExtension(ProtocolKey.SEQ_NUM)).toString(); - - final String uniqueId = cloudEvent.getExtension(ProtocolKey.UNIQUE_ID) == null - ? RandomStringUtils.generateNum(30) - : Objects.requireNonNull(cloudEvent.getExtension(ProtocolKey.UNIQUE_ID)).toString(); - - final 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); - - cloudEvent.getExtensionNames().forEach(extName -> { - builder.putProperties(extName, Objects.requireNonNull(cloudEvent.getExtension(extName)).toString()); - }); - return builder.build(); - } - - @SuppressWarnings("unchecked") - public static BatchMessage buildBatchMessages(final List messageList, final EventMeshGrpcClientConfig clientConfig, - final EventMeshProtocolType protocolType) { - - switch (protocolType) { - case CLOUD_EVENTS: - return switchCloudEvents2BatchMessage((List) messageList, clientConfig, protocolType); - case EVENT_MESH_MESSAGE: - return switchEventMessages2BatchMessage((List) messageList, clientConfig, protocolType); - case OPEN_MESSAGE: - default: - return null; - } - } - - private static BatchMessage switchEventMessages2BatchMessage(List messageList, EventMeshGrpcClientConfig clientConfig, - EventMeshProtocolType protocolType) { - - final List eventMeshMessages = messageList; - final BatchMessage.Builder messageBuilder = BatchMessage.newBuilder() - .setHeader(EventMeshClientUtil.buildHeader(clientConfig, protocolType)) - .setProducerGroup(clientConfig.getProducerGroup()) - .setTopic(eventMeshMessages.get(0).getTopic()); - - eventMeshMessages.forEach(message -> { - 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(); - } - - private static BatchMessage switchCloudEvents2BatchMessage(List messageList, EventMeshGrpcClientConfig clientConfig, - EventMeshProtocolType protocolType) { - List events = messageList; - BatchMessage.Builder messageBuilder = BatchMessage.newBuilder() - .setHeader(EventMeshClientUtil.buildHeader(clientConfig, protocolType)) - .setProducerGroup(clientConfig.getProducerGroup()) - .setTopic(events.get(0).getSubject()); - - events.forEach(event -> { - final String contentType = StringUtils.isEmpty(event.getDataContentType()) - ? Constants.CONTENT_TYPE_CLOUDEVENTS_JSON : event.getDataContentType(); - - final byte[] bodyByte = Objects.requireNonNull(EventFormatProvider.getInstance().resolveFormat(contentType)).serialize(event); - final String content = new String(bodyByte, Constants.DEFAULT_CHARSET); - final String ttl = event.getExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL) == null - ? Constants.DEFAULT_EVENTMESH_MESSAGE_TTL - : Objects.requireNonNull(event.getExtension(Constants.EVENTMESH_MESSAGE_CONST_TTL)).toString(); - - BatchMessage.MessageItem messageItem = BatchMessage.MessageItem.newBuilder() - .setContent(content) - .setTtl(ttl) - .setSeqNum(Objects.requireNonNull(event.getExtension(ProtocolKey.SEQ_NUM)).toString()) - .setUniqueId(Objects.requireNonNull(event.getExtension(ProtocolKey.UNIQUE_ID)).toString()) - .putProperties(ProtocolKey.CONTENT_TYPE, contentType) - .build(); - messageBuilder.addMessageItem(messageItem); - }); - return messageBuilder.build(); - } -} diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/util/EventMeshCloudEventBuilder.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/util/EventMeshCloudEventBuilder.java new file mode 100644 index 0000000000..f89715054b --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/grpc/util/EventMeshCloudEventBuilder.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.client.grpc.util; + +import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.client.grpc.exception.ProtocolNotSupportException; +import org.apache.eventmesh.common.Constants; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.enums.EventMeshProtocolType; +import org.apache.eventmesh.common.protocol.SubscriptionItem; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.ProtoSupport; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +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.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +import java.net.URI; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +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.protobuf.ProtobufFormat; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.google.protobuf.Any; +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EventMeshCloudEventBuilder { + + private static final String CLOUD_EVENT_TYPE = "org.apache.eventmesh"; + + private static final EventFormat eventProtoFormat = EventFormatProvider.getInstance().resolveFormat(ProtobufFormat.PROTO_CONTENT_TYPE); + + public static Map buildCommonCloudEventAttributes(EventMeshGrpcClientConfig clientConfig, + EventMeshProtocolType protocolType) { + final Map attributeValueMap = new HashMap<>(64); + attributeValueMap.put(ProtocolKey.ENV, CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getEnv()).build()); + attributeValueMap.put(ProtocolKey.IDC, CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getIdc()).build()); + attributeValueMap.put(ProtocolKey.IP, CloudEventAttributeValue.newBuilder().setCeString(IPUtils.getLocalAddress()).build()); + attributeValueMap.put(ProtocolKey.PID, CloudEventAttributeValue.newBuilder().setCeString(Long.toString(ThreadUtils.getPID())).build()); + attributeValueMap.put(ProtocolKey.SYS, CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getSys()).build()); + attributeValueMap.put(ProtocolKey.LANGUAGE, CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getLanguage()).build()); + attributeValueMap.put(ProtocolKey.USERNAME, CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getUserName()).build()); + attributeValueMap.put(ProtocolKey.PASSWD, CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getPassword()).build()); + attributeValueMap.put(ProtocolKey.PROTOCOL_TYPE, CloudEventAttributeValue.newBuilder().setCeString(protocolType.protocolTypeName()).build()); + attributeValueMap.put(ProtocolKey.PROTOCOL_VERSION, CloudEventAttributeValue.newBuilder().setCeString(SpecVersion.V1.toString()).build()); + + return attributeValueMap; + } + + public static CloudEvent buildEventSubscription(EventMeshGrpcClientConfig clientConfig, EventMeshProtocolType protocolType, String url, + List subscriptionItems) { + + if (CollectionUtils.isEmpty(subscriptionItems)) { + return null; + } + Set subscriptionItemSet = new HashSet<>(); + subscriptionItemSet.addAll(subscriptionItems); + + final Map attributeValueMap = buildCommonCloudEventAttributes(clientConfig, protocolType); + attributeValueMap.put(ProtocolKey.CONSUMERGROUP, CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getConsumerGroup()).build()); + attributeValueMap.put(ProtocolKey.DATA_CONTENT_TYPE, CloudEventAttributeValue.newBuilder().setCeString("application/json").build()); + if (StringUtils.isNotBlank(url)) { + attributeValueMap.put(ProtocolKey.URL, CloudEventAttributeValue.newBuilder().setCeString(url).build()); + } + return CloudEvent.newBuilder() + .setId(RandomStringUtils.generateUUID()) + .setSource(URI.create("/").toString()) + .setSpecVersion(SpecVersion.V1.toString()) + .setType(CLOUD_EVENT_TYPE) + .setTextData(JsonUtils.toJSONString(subscriptionItemSet)) + .putAllAttributes(attributeValueMap) + .build(); + } + + /** + * @param message + * @param clientConfig + * @param protocolType + * @param + * @return CloudEvent + * @see context-attributes + */ + public static CloudEvent buildEventMeshCloudEvent(final T message, final EventMeshGrpcClientConfig clientConfig, + final EventMeshProtocolType protocolType) { + + switch (protocolType) { + case CLOUD_EVENTS: { + if (!(message instanceof io.cloudevents.CloudEvent)) { + throw new ClassCastException(message.getClass().getName() + " can not cast io.cloudevents.CloudEvent"); + } + return switchCloudEvent2EventMeshCloudEvent((io.cloudevents.CloudEvent) message, clientConfig, protocolType); + } + case EVENT_MESH_MESSAGE: { + if (!(message instanceof EventMeshMessage)) { + throw new ClassCastException(message.getClass().getName() + " can not cast" + EventMeshMessage.class.getName()); + } + return switchEventMeshMessage2EventMeshCloudEvent((EventMeshMessage) message, clientConfig, protocolType); + } + case OPEN_MESSAGE: + return null; + default: + throw new ProtocolNotSupportException("Protocol Type [" + protocolType + "] not support"); + } + } + + private static CloudEvent switchEventMeshMessage2EventMeshCloudEvent(EventMeshMessage message, EventMeshGrpcClientConfig clientConfig, + EventMeshProtocolType protocolType) { + final String ttl = message.getProp(Constants.EVENTMESH_MESSAGE_CONST_TTL) == null + ? Constants.DEFAULT_EVENTMESH_MESSAGE_TTL + : message.getProp(Constants.EVENTMESH_MESSAGE_CONST_TTL); + final Map props = message.getProp() == null ? new HashMap<>() : message.getProp(); + final String seqNum = message.getBizSeqNo() == null ? RandomStringUtils.generateNum(30) : message.getBizSeqNo(); + final String uniqueId = message.getUniqueId() == null ? RandomStringUtils.generateNum(30) : message.getUniqueId(); + final String dataContentType = props.computeIfAbsent(ProtocolKey.DATA_CONTENT_TYPE, key -> "text/plain"); + final Map attributeValueMap = buildCommonCloudEventAttributes(clientConfig, protocolType); + + attributeValueMap.put(ProtocolKey.TTL, CloudEventAttributeValue.newBuilder().setCeString(ttl).build()); + attributeValueMap.put(ProtocolKey.SEQ_NUM, CloudEventAttributeValue.newBuilder().setCeString(seqNum).build()); + attributeValueMap.put(ProtocolKey.UNIQUE_ID, CloudEventAttributeValue.newBuilder().setCeString(uniqueId).build()); + attributeValueMap.put(ProtocolKey.PROTOCOL_DESC, + CloudEventAttributeValue.newBuilder().setCeString(Constants.PROTOCOL_DESC_GRPC_CLOUD_EVENT).build()); + attributeValueMap.put(ProtocolKey.PRODUCERGROUP, + CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getProducerGroup()).build()); + if (null != message.getTopic()) { + attributeValueMap.put(ProtocolKey.SUBJECT, CloudEventAttributeValue.newBuilder().setCeString(message.getTopic()).build()); + } + attributeValueMap.put(ProtocolKey.DATA_CONTENT_TYPE, CloudEventAttributeValue.newBuilder().setCeString("text/plain").build()); + props.forEach((key, value) -> attributeValueMap.put(key, CloudEventAttributeValue.newBuilder().setCeString(value).build())); + CloudEvent.Builder builder = CloudEvent.newBuilder() + .setId(RandomStringUtils.generateUUID()) + .setSource(URI.create("/").toString()) + .setSpecVersion(SpecVersion.V1.toString()) + .setType(CLOUD_EVENT_TYPE) + .putAllAttributes(attributeValueMap); + final String content = message.getContent(); + if (StringUtils.isNotEmpty(content)) { + if (ProtoSupport.isTextContent(dataContentType)) { + builder.setTextData(content); + } else if (ProtoSupport.isProtoContent(dataContentType)) { + try { + Any dataAsAny = Any.parseFrom(content.getBytes(Constants.DEFAULT_CHARSET)); + builder.setProtoData(dataAsAny); + } catch (InvalidProtocolBufferException e) { + throw new IllegalArgumentException("parse from byte[] to com.google.protobuf.Any error", e); + } + } else { + ByteString byteString = ByteString.copyFrom(content.getBytes(Constants.DEFAULT_CHARSET)); + builder.setBinaryData(byteString); + } + } + return builder.build(); + } + + private static CloudEvent switchCloudEvent2EventMeshCloudEvent(io.cloudevents.CloudEvent message, EventMeshGrpcClientConfig clientConfig, + EventMeshProtocolType protocolType) { + + CloudEventBuilder cloudEventBuilder = CloudEventBuilder.from(message); + + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.ENV, clientConfig.getEnv()); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.IDC, clientConfig.getIdc()); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.IP, Objects.requireNonNull(IPUtils.getLocalAddress())); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.PID, Long.toString(ThreadUtils.getPID())); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.SYS, clientConfig.getSys()); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.PROTOCOL_TYPE, protocolType.protocolTypeName()); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.PROTOCOL_DESC, Constants.PROTOCOL_DESC_GRPC_CLOUD_EVENT); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.PROTOCOL_VERSION, message.getSpecVersion().toString()); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.UNIQUE_ID, RandomStringUtils.generateNum(30)); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.SEQ_NUM, RandomStringUtils.generateNum(30)); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.USERNAME, clientConfig.getUserName()); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.PASSWD, clientConfig.getPassword()); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.PRODUCERGROUP, clientConfig.getProducerGroup()); + buildCloudEventIfAbsent(message, cloudEventBuilder, ProtocolKey.TTL, Constants.DEFAULT_EVENTMESH_MESSAGE_TTL); + + try { + return CloudEvent.parseFrom(eventProtoFormat.serialize(cloudEventBuilder.build())); + } catch (InvalidProtocolBufferException exc) { + log.error("Parse from CloudEvents CloudEvent bytes to EventMesh CloudEvent error", exc); + } + return null; + } + + private static void buildCloudEventIfAbsent(io.cloudevents.CloudEvent message, CloudEventBuilder cloudEventBuilder, + String extension, String value) { + if (Objects.isNull(message.getExtension(extension))) { + cloudEventBuilder.withExtension(extension, value); + } + } + + public static CloudEventBatch buildEventMeshCloudEventBatch(final List messageList, final EventMeshGrpcClientConfig clientConfig, + final EventMeshProtocolType protocolType) { + if (CollectionUtils.isEmpty(messageList)) { + return null; + } + List cloudEventList = messageList.stream().map(item -> buildEventMeshCloudEvent(item, clientConfig, protocolType)) + .collect(Collectors.toList()); + return CloudEventBatch.newBuilder().addAllEvents(cloudEventList).build(); + } + + @SuppressWarnings("unchecked") + public static T buildMessageFromEventMeshCloudEvent(final CloudEvent cloudEvent, final EventMeshProtocolType protocolType) { + + if (null == cloudEvent) { + return null; + } + final String seq = EventMeshCloudEventUtils.getSeqNum(cloudEvent); + final String uniqueId = EventMeshCloudEventUtils.getUniqueId(cloudEvent); + final String content = EventMeshCloudEventUtils.getDataContent(cloudEvent); + + // This is GRPC response cloudEvent + if (StringUtils.isEmpty(seq) && StringUtils.isEmpty(uniqueId)) { + // The SubscriptionItem collection contains the content for the subscription. + return (T) JsonUtils.parseTypeReferenceObject(content, + new TypeReference>>() { + + }); + } + if (null == protocolType) { + return null; + } + + switch (protocolType) { + case CLOUD_EVENTS: + return (T) switchEventMeshCloudEvent2CloudEvent(cloudEvent); + case EVENT_MESH_MESSAGE: + return (T) switchEventMeshCloudEvent2EventMeshMessage(cloudEvent); + case OPEN_MESSAGE: + default: + return null; + } + } + + private static io.cloudevents.CloudEvent switchEventMeshCloudEvent2CloudEvent(final CloudEvent cloudEvent) { + + return eventProtoFormat.deserialize(Objects.requireNonNull(cloudEvent).toByteArray()); + } + + private static EventMeshMessage switchEventMeshCloudEvent2EventMeshMessage(final CloudEvent cloudEvent) { + Map prop = new HashMap<>(); + Objects.requireNonNull(cloudEvent).getAttributesMap().forEach((key, value) -> prop.put(key, value.getCeString())); + return EventMeshMessage.builder() + .content(cloudEvent.getTextData()) + .topic(EventMeshCloudEventUtils.getSubject(cloudEvent)) + .bizSeqNo(EventMeshCloudEventUtils.getSeqNum(cloudEvent)) + .uniqueId(EventMeshCloudEventUtils.getUniqueId(cloudEvent)) + .prop(prop) + .build(); + } + +} \ No newline at end of file diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/AbstractProducerHttpClient.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/AbstractProducerHttpClient.java index a1e6ed27d7..55b5bc91db 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/AbstractProducerHttpClient.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/AbstractProducerHttpClient.java @@ -38,7 +38,7 @@ public abstract class AbstractProducerHttpClient extends AbstractHttpClient implements EventMeshProtocolProducer { public AbstractProducerHttpClient(final EventMeshHttpClientConfig eventMeshHttpClientConfig) - throws EventMeshException { + throws EventMeshException { super(eventMeshHttpClientConfig); } @@ -91,7 +91,6 @@ public void request(final T message, final RRCallback rrCallback, final long public abstract RequestParam builderRequestParam(T t, long timeout); - public abstract void validateMessage(T t); public abstract T transformMessage(EventMeshRetObj retObj); diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/EventMeshRetObj.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/EventMeshRetObj.java index 58337dbc44..fe024fcf5f 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/EventMeshRetObj.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/EventMeshRetObj.java @@ -17,7 +17,6 @@ package org.apache.eventmesh.client.http; - public class EventMeshRetObj { private long resTime; diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ProtocolConstant.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ProtocolConstant.java index f7f217bbb4..1ea894a183 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ProtocolConstant.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ProtocolConstant.java @@ -19,7 +19,6 @@ 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-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/consumer/EventMeshHttpConsumer.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/consumer/EventMeshHttpConsumer.java index fa48bd618e..6e9b94bec7 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/consumer/EventMeshHttpConsumer.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/consumer/EventMeshHttpConsumer.java @@ -66,13 +66,11 @@ public EventMeshHttpConsumer(final EventMeshHttpClientConfig eventMeshHttpClient } public EventMeshHttpConsumer(final EventMeshHttpClientConfig eventMeshHttpClientConfig, - final ThreadPoolExecutor customExecutor) - throws EventMeshException { + final ThreadPoolExecutor customExecutor) throws EventMeshException { super(eventMeshHttpClientConfig); this.consumeExecutor = Optional.ofNullable(customExecutor).orElseGet( () -> ThreadPoolFactory.createThreadPoolExecutor(eventMeshHttpClientConfig.getConsumeThreadCore(), - eventMeshHttpClientConfig.getConsumeThreadMax(), "EventMesh-client-consume") - ); + eventMeshHttpClientConfig.getConsumeThreadMax(), "EventMesh-client-consume")); this.scheduler = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), new EventMeshThreadFactory("HTTPClientScheduler", true)); } @@ -114,11 +112,10 @@ public void heartBeat(final List topicList, final String subsc scheduler.scheduleAtFixedRate(() -> { try { - final List heartbeatEntities = topicList.stream().map(subscriptionItem - -> { + final List heartbeatEntities = topicList.stream().map(subscriptionItem -> { final HeartbeatRequestBody.HeartbeatEntity heartbeatEntity = new HeartbeatRequestBody.HeartbeatEntity(); - heartbeatEntity.topic = subscriptionItem.getTopic(); - heartbeatEntity.url = subscribeUrl; + heartbeatEntity.setTopic(subscriptionItem.getTopic()); + heartbeatEntity.setUrl(subscribeUrl); return heartbeatEntity; }).collect(Collectors.toList()); @@ -169,9 +166,7 @@ public void unsubscribe(final List topicList, final String unSubscribeUr @Override public void close() throws EventMeshException { - if (log.isInfoEnabled()) { - log.info("LiteConsumer shutdown begin."); - } + log.info("LiteConsumer shutdown begin."); super.close(); if (consumeExecutor != null) { @@ -179,20 +174,18 @@ public void close() throws EventMeshException { } scheduler.shutdown(); - if (log.isInfoEnabled()) { - log.info("LiteConsumer shutdown end."); - } + log.info("LiteConsumer shutdown end."); } 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()) + .addHeader(ProtocolKey.ClientInstanceKey.ENV.getKey(), eventMeshHttpClientConfig.getEnv()) + .addHeader(ProtocolKey.ClientInstanceKey.IDC.getKey(), eventMeshHttpClientConfig.getIdc()) + .addHeader(ProtocolKey.ClientInstanceKey.IP.getKey(), eventMeshHttpClientConfig.getIp()) + .addHeader(ProtocolKey.ClientInstanceKey.PID.getKey(), eventMeshHttpClientConfig.getPid()) + .addHeader(ProtocolKey.ClientInstanceKey.SYS.getKey(), eventMeshHttpClientConfig.getSys()) + .addHeader(ProtocolKey.ClientInstanceKey.USERNAME.getKey(), eventMeshHttpClientConfig.getUserName()) + .addHeader(ProtocolKey.ClientInstanceKey.PASSWD.getKey(), eventMeshHttpClientConfig.getPassword()) // add protocol version? .addHeader(ProtocolKey.VERSION, ProtocolVersion.V1.getVersion()) .addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/CloudEventProducer.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/CloudEventProducer.java index 63645f3e0e..27ab2896a8 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/CloudEventProducer.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/CloudEventProducer.java @@ -82,15 +82,15 @@ private RequestParam buildCommonPostParam(final CloudEvent cloudEvent) { final 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.ClientInstanceKey.ENV.getKey(), eventMeshHttpClientConfig.getEnv()) + .addHeader(ProtocolKey.ClientInstanceKey.IDC.getKey(), eventMeshHttpClientConfig.getIdc()) + .addHeader(ProtocolKey.ClientInstanceKey.IP.getKey(), eventMeshHttpClientConfig.getIp()) + .addHeader(ProtocolKey.ClientInstanceKey.PID.getKey(), eventMeshHttpClientConfig.getPid()) + .addHeader(ProtocolKey.ClientInstanceKey.SYS.getKey(), eventMeshHttpClientConfig.getSys()) + .addHeader(ProtocolKey.ClientInstanceKey.USERNAME.getKey(), eventMeshHttpClientConfig.getUserName()) + .addHeader(ProtocolKey.ClientInstanceKey.PASSWD.getKey(), eventMeshHttpClientConfig.getPassword()) .addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) - .addHeader(ProtocolKey.PROTOCOL_TYPE, ProtocolConstant.CE_PROTOCOL) + .addHeader(ProtocolKey.PROTOCOL_TYPE, Constants.CLOUD_EVENTS_PROTOCOL_NAME) .addHeader(ProtocolKey.PROTOCOL_DESC, ProtocolConstant.PROTOCOL_DESC) .addHeader(ProtocolKey.PROTOCOL_VERSION, cloudEvent.getSpecVersion().toString()) @@ -102,16 +102,16 @@ private RequestParam buildCommonPostParam(final CloudEvent cloudEvent) { 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.ClientInstanceKey.ENV.getKey(), eventMeshHttpClientConfig.getEnv()) + .withExtension(ProtocolKey.ClientInstanceKey.IDC.getKey(), eventMeshHttpClientConfig.getIdc()) + .withExtension(ProtocolKey.ClientInstanceKey.IP.getKey(), eventMeshHttpClientConfig.getIp()) + .withExtension(ProtocolKey.ClientInstanceKey.PID.getKey(), eventMeshHttpClientConfig.getPid()) + .withExtension(ProtocolKey.ClientInstanceKey.SYS.getKey(), 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)) + .withExtension(ProtocolKey.ClientInstanceKey.BIZSEQNO.getKey(), RandomStringUtils.generateNum(30)) + .withExtension(ProtocolKey.ClientInstanceKey.UNIQUEID.getKey(), RandomStringUtils.generateNum(30)) .build(); } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshMessageProducer.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshMessageProducer.java index 5ba3f0feaa..f0f471c39e 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshMessageProducer.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/EventMeshMessageProducer.java @@ -70,17 +70,17 @@ public void validateMessage(final EventMeshMessage message) { private RequestParam buildCommonPostParam(final EventMeshMessage message) { final 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.ClientInstanceKey.ENV.getKey(), eventMeshHttpClientConfig.getEnv()) + .addHeader(ProtocolKey.ClientInstanceKey.IDC.getKey(), eventMeshHttpClientConfig.getIdc()) + .addHeader(ProtocolKey.ClientInstanceKey.IP.getKey(), eventMeshHttpClientConfig.getIp()) + .addHeader(ProtocolKey.ClientInstanceKey.PID.getKey(), eventMeshHttpClientConfig.getPid()) + .addHeader(ProtocolKey.ClientInstanceKey.SYS.getKey(), eventMeshHttpClientConfig.getSys()) + .addHeader(ProtocolKey.ClientInstanceKey.USERNAME.getKey(), eventMeshHttpClientConfig.getUserName()) + .addHeader(ProtocolKey.ClientInstanceKey.PASSWD.getKey(), 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 + // default ce version is 1.0 .addHeader(ProtocolKey.PROTOCOL_VERSION, SpecVersion.V1.toString()) .addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) .addBody(SendMessageRequestBody.PRODUCERGROUP, eventMeshHttpClientConfig.getProducerGroup()) diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/OpenMessageProducer.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/OpenMessageProducer.java index 6e2b4828ea..877fb3476a 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/OpenMessageProducer.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/producer/OpenMessageProducer.java @@ -41,7 +41,7 @@ class OpenMessageProducer extends AbstractProducerHttpClient { public OpenMessageProducer(final EventMeshHttpClientConfig eventMeshHttpClientConfig) - throws EventMeshException { + throws EventMeshException { super(eventMeshHttpClientConfig); } @@ -66,8 +66,8 @@ public void validateMessage(final Message message) { private RequestParam buildCommonPostParam(final Message openMessage) { final RequestParam requestParam = new RequestParam(HttpMethod.POST); requestParam - .addHeader(ProtocolKey.ClientInstanceKey.USERNAME, eventMeshHttpClientConfig.getUserName()) - .addHeader(ProtocolKey.ClientInstanceKey.PASSWD, eventMeshHttpClientConfig.getPassword()) + .addHeader(ProtocolKey.ClientInstanceKey.USERNAME.getKey(), eventMeshHttpClientConfig.getUserName()) + .addHeader(ProtocolKey.ClientInstanceKey.PASSWD.getKey(), eventMeshHttpClientConfig.getPassword()) .addHeader(ProtocolKey.LANGUAGE, Constants.LANGUAGE_JAVA) .addHeader(ProtocolKey.PROTOCOL_TYPE, ProtocolConstant.OP_MESSAGE_PROTOCOL) .addHeader(ProtocolKey.PROTOCOL_DESC, ProtocolConstant.PROTOCOL_DESC) diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ssl/MyX509TrustManager.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ssl/MyX509TrustManager.java index c9fb011372..0b01ae75df 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ssl/MyX509TrustManager.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/ssl/MyX509TrustManager.java @@ -48,7 +48,8 @@ public MyX509TrustManager() throws KeyStoreException, IOException, CertificateEx try (InputStream in = Files.newInputStream( Paths.get(System.getProperty("confPath", System.getenv("confPath")) - + File.separator + fileName), StandardOpenOption.READ)) { + + File.separator + fileName), + StandardOpenOption.READ)) { keyStore.load(in, filePass); } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtils.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtils.java index 3f2646ae03..bad7183766 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtils.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtils.java @@ -84,8 +84,7 @@ private static List> buildWeightedClusterGroupFromConfig( final int splitIndex = eventMeshAddrWight.lastIndexOf(":"); final Weight weight = new Weight<>( eventMeshAddrWight.substring(0, splitIndex), - Integer.parseInt(eventMeshAddrWight.substring(splitIndex + 1)) - ); + Integer.parseInt(eventMeshAddrWight.substring(splitIndex + 1))); eventMeshAddrWeightList.add(weight); } return eventMeshAddrWeightList; diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpUtils.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpUtils.java index 8e07b25e08..93a9313999 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpUtils.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/http/util/HttpUtils.java @@ -80,14 +80,14 @@ public static String post(final CloseableHttpClient client, final HttpPost httpPost = new HttpPost(uri); - //header + // header if (MapUtils.isNotEmpty(requestParam.getHeaders())) { for (final Map.Entry entry : requestParam.getHeaders().entrySet()) { httpPost.addHeader(entry.getKey(), entry.getValue()); } } - //body + // body if (MapUtils.isNotEmpty(requestParam.getBody())) { final List pairs = new ArrayList<>(); for (final Map.Entry entry : requestParam.getBody().entrySet()) { @@ -96,7 +96,7 @@ public static String post(final CloseableHttpClient client, httpPost.setEntity(new UrlEncodedFormEntity(pairs, Constants.DEFAULT_CHARSET)); } - //ttl + // ttl final RequestConfig.Builder configBuilder = RequestConfig.custom(); configBuilder.setSocketTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))) .setConnectTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))) @@ -108,9 +108,7 @@ public static String post(final CloseableHttpClient client, httpPost.setConfig(configBuilder.build()); - if (log.isDebugEnabled()) { - log.debug("{}", httpPost); - } + log.debug("{}", httpPost); return client.execute(httpPost, responseHandler); } @@ -143,14 +141,14 @@ public static String get(final CloseableHttpClient client, final HttpGet httpGet = new HttpGet(MapUtils.isNotEmpty(requestParam.getQueryParamsMap()) ? uri + "?" + requestParam.getQueryParams() : uri); - //header + // header if (MapUtils.isNotEmpty(requestParam.getHeaders())) { for (final Map.Entry entry : requestParam.getHeaders().entrySet()) { httpGet.addHeader(entry.getKey(), entry.getValue()); } } - //ttl + // ttl final RequestConfig.Builder configBuilder = RequestConfig.custom(); configBuilder.setSocketTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))) .setConnectTimeout(Integer.parseInt(String.valueOf(requestParam.getTimeout()))) @@ -162,9 +160,7 @@ public static String get(final CloseableHttpClient client, httpGet.setConfig(configBuilder.build()); - if (log.isDebugEnabled()) { - log.debug("{}", httpGet); - } + log.debug("{}", httpGet); return client.execute(httpGet, responseHandler); } @@ -183,7 +179,7 @@ private static class EventMeshResponseHandler implements ResponseHandler public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException { int statusCode = response.getStatusLine().getStatusCode(); - //Successful responses (200-299) + // Successful responses (200-299) if (statusCode >= 200 && statusCode < 300) { HttpEntity entity = response.getEntity(); return entity != null ? EntityUtils.toString(entity, Constants.DEFAULT_CHARSET) : null; diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/EventMeshCommon.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/EventMeshCommon.java index 606b24cfe4..902a135221 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/EventMeshCommon.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/EventMeshCommon.java @@ -39,8 +39,6 @@ public class EventMeshCommon { */ 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-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/MessageUtils.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/MessageUtils.java index 17c911b568..2232e539c9 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/MessageUtils.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/MessageUtils.java @@ -17,6 +17,8 @@ package org.apache.eventmesh.client.tcp.common; +import static org.apache.eventmesh.common.Constants.CLOUD_EVENTS_PROTOCOL_NAME; + import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.protocol.SubscriptionItem; import org.apache.eventmesh.common.protocol.SubscriptionMode; @@ -28,7 +30,6 @@ 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; @@ -46,58 +47,44 @@ public class MessageUtils { private static final int SEQ_LENGTH = 10; public static Package hello(UserAgent user) { - final Package msg = new Package(); - msg.setHeader(new Header(Command.HELLO_REQUEST, 0, null, generateRandomString())); + final Package msg = getPackage(Command.HELLO_REQUEST); msg.setBody(user); return msg; } public static Package heartBeat() { - final Package msg = new Package(); - msg.setHeader(new Header(Command.HEARTBEAT_REQUEST, 0, null, generateRandomString())); - return msg; + return getPackage(Command.HEARTBEAT_REQUEST); } public static Package goodbye() { - final Package msg = new Package(); - msg.setHeader(new Header(Command.CLIENT_GOODBYE_REQUEST, 0, null, generateRandomString())); - return msg; + return getPackage(Command.CLIENT_GOODBYE_REQUEST); } public static Package listen() { - final Package msg = new Package(); - msg.setHeader(new Header(Command.LISTEN_REQUEST, 0, null, generateRandomString())); - return msg; + return getPackage(Command.LISTEN_REQUEST); } public static Package subscribe(String topic, SubscriptionMode subscriptionMode, SubscriptionType subscriptionType) { - Package msg = new Package(); - msg.setHeader(new Header(Command.SUBSCRIBE_REQUEST, 0, null, generateRandomString())); + Package msg = getPackage(Command.SUBSCRIBE_REQUEST); msg.setBody(generateSubscription(topic, subscriptionMode, subscriptionType)); return msg; } public static Package unsubscribe() { - final Package msg = new Package(); - msg.setHeader(new Header(Command.UNSUBSCRIBE_REQUEST, 0, null, generateRandomString())); - return msg; + return getPackage(Command.UNSUBSCRIBE_REQUEST); } public static Package asyncMessageAck(Package in) { - final 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; + return getPackage(Command.ASYNC_MESSAGE_TO_CLIENT_ACK, in); } public static Package buildPackage(Object message, Command command) { - final Package msg = new Package(); - msg.setHeader(new Header(command, 0, null, generateRandomString())); + final Package msg = getPackage(command); if (message instanceof CloudEvent) { final 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_TYPE, CLOUD_EVENTS_PROTOCOL_NAME); msg.getHeader().putProperty(Constants.PROTOCOL_VERSION, cloudEvent.getSpecVersion().toString()); msg.getHeader().putProperty(Constants.PROTOCOL_DESC, "tcp"); @@ -122,58 +109,23 @@ public static Package buildPackage(Object message, Command command) { } public static Package broadcastMessageAck(Package in) { - final 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; + return getPackage(Command.BROADCAST_MESSAGE_TO_CLIENT_ACK, in); } 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; + return getPackage(Command.REQUEST_TO_CLIENT_ACK, in); } public static Package responseToClientAck(Package in) { - final Package msg = new Package(); - msg.setHeader(new Header(Command.RESPONSE_TO_CLIENT_ACK, 0, null, in.getHeader().getSeq())); - msg.setBody(in.getBody()); - return msg; + return getPackage(Command.RESPONSE_TO_CLIENT_ACK, in); } 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(); + return getUserAgent(agent, EventMeshCommon.USER_AGENT_PURPOSE_SUB); } 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(); + return getUserAgent(agent, EventMeshCommon.USER_AGENT_PURPOSE_PUB); } private static Subscription generateSubscription(String topic, SubscriptionMode subscriptionMode, @@ -191,4 +143,38 @@ private static String generateRandomString() { return builder.toString(); } + + private static Package getPackage(Command command) { + final Package msg = new Package(); + msg.setHeader(new Header(command, 0, null, generateRandomString())); + return msg; + } + + private static Package getPackage(Command command, String seq, Object body) { + final Package msg = new Package(); + msg.setHeader(new Header(command, 0, null, seq)); + msg.setBody(body); + return msg; + } + + private static Package getPackage(Command command, Package in) { + return getPackage(command, in.getHeader().getSeq(), in.getBody()); + } + + private static UserAgent getUserAgent(UserAgent agent, String purpose) { + 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(purpose) + .build(); + } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/RequestContext.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/RequestContext.java index 8f9256ef32..0508d03821 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/RequestContext.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/RequestContext.java @@ -72,13 +72,10 @@ public void finish(final Package msg) { public static RequestContext context(final Object key, final Package request) throws Exception { final RequestContext context = new RequestContext(key, request); - if (log.isInfoEnabled()) { - log.info("_RequestContext|create|key={}", key); - } + log.info("_RequestContext|create|key={}", key); return context; } - public static Object key(final Package request) { return request.getHeader().getSeq(); } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java index d904d55fbd..4619f550e7 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/common/TcpClient.java @@ -61,7 +61,7 @@ public abstract class TcpClient implements Closeable { protected static transient int CLIENTNO = 0; - + static { try { CLIENTNO = SecureRandom.getInstanceStrong().nextInt(1000); @@ -106,6 +106,7 @@ protected synchronized void open(SimpleChannelInboundHandler handler) t .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(1024, 8192, 65536)) .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); bootstrap.handler(new ChannelInitializer() { + @Override public void initChannel(SocketChannel ch) { ch.pipeline().addLast(new Codec.Encoder(), new Codec.Decoder()) @@ -116,10 +117,7 @@ public void initChannel(SocketChannel ch) { ChannelFuture f = bootstrap.connect(host, port).sync(); InetSocketAddress localAddress = (InetSocketAddress) f.channel().localAddress(); channel = f.channel(); - if (log.isInfoEnabled()) { - log.info("connected|local={}:{}|server={}", localAddress.getAddress().getHostAddress(), - localAddress.getPort(), host + ":" + port); - } + log.info("connected|local={}:{}|server={}", localAddress.getAddress().getHostAddress(), localAddress.getPort(), host + ":" + port); } @Override @@ -133,10 +131,7 @@ public void close() { goodbye(); } catch (Exception e) { Thread.currentThread().interrupt(); - - if (log.isWarnEnabled()) { - log.warn("close tcp client failed.|remote address={}", channel.remoteAddress(), e); - } + log.warn("close tcp client failed.|remote address={}", channel.remoteAddress(), e); } } @@ -150,9 +145,7 @@ protected void heartbeat() { } Package msg = MessageUtils.heartBeat(); io(msg, EventMeshCommon.DEFAULT_TIME_OUT_MILLS); - if (log.isDebugEnabled()) { - log.debug("heart beat start {}", msg); - } + log.debug("heart beat start {}", msg); } catch (Exception e) { // ignore } @@ -174,9 +167,7 @@ protected void send(Package msg) throws Exception { if (channel.isWritable()) { channel.writeAndFlush(msg).addListener((ChannelFutureListener) future -> { if (!future.isSuccess()) { - if (log.isWarnEnabled()) { - log.warn("send msg failed", future.cause()); - } + log.warn("send msg failed", future.cause()); } }); } else { @@ -187,12 +178,9 @@ protected void send(Package msg) throws Exception { protected Package io(Package msg, long timeout) throws Exception { Object key = RequestContext.key(msg); RequestContext context = RequestContext.context(key, msg); - if (!contexts.contains(context)) { - contexts.put(key, context); - } else { - if (log.isInfoEnabled()) { - log.info("duplicate key : {}", key); - } + RequestContext previousContext = contexts.putIfAbsent(key, context); + if (previousContext != null) { + log.info("duplicate key : {}", key); } send(msg); Supplier supplier = () -> { @@ -219,12 +207,10 @@ protected void goodbye() throws Exception { private ChannelDuplexHandler newExceptionHandler() { return new ChannelDuplexHandler() { + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - if (log.isInfoEnabled()) { - log.info("exceptionCaught, close connection.|remote address={}", - ctx.channel().remoteAddress(), cause); - } + log.info("exceptionCaught, close connection.|remote address={}", ctx.channel().remoteAddress(), cause); ctx.close(); } }; diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPPubHandler.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPPubHandler.java index b83865991a..880dd12cd2 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPPubHandler.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/AbstractEventMeshTCPPubHandler.java @@ -52,7 +52,7 @@ protected void channelRead0(ChannelHandlerContext ctx, Package msg) { sendResponse(MessageUtils.responseToClientAck(msg)); break; case SERVER_GOODBYE_REQUEST: - //TODO + // TODO break; default: break; diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPPubClient.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPPubClient.java index ed98bbce4d..35f2186b34 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPPubClient.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPPubClient.java @@ -37,6 +37,7 @@ import io.cloudevents.core.format.EventFormat; import io.cloudevents.core.provider.EventFormatProvider; import io.cloudevents.jackson.JsonFormat; +import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; import com.google.common.base.Preconditions; @@ -138,6 +139,7 @@ public void close() { } } + @Sharable private class CloudEventTCPPubHandler extends AbstractEventMeshTCPPubHandler { public CloudEventTCPPubHandler(ConcurrentHashMap contexts) { diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPSubClient.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPSubClient.java index dbebc6dcc6..836ad00dc5 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPSubClient.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/cloudevent/CloudEventTCPSubClient.java @@ -35,8 +35,8 @@ import org.apache.commons.collections4.CollectionUtils; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -44,6 +44,7 @@ import io.cloudevents.core.format.EventFormat; import io.cloudevents.core.provider.EventFormatProvider; import io.cloudevents.jackson.JsonFormat; +import io.netty.channel.ChannelHandler.Sharable; import io.netty.channel.ChannelHandlerContext; import com.google.common.base.Preconditions; @@ -56,7 +57,7 @@ @Slf4j class CloudEventTCPSubClient extends TcpClient implements EventMeshTCPSubClient { - private final List subscriptionItems = Collections.synchronizedList(new LinkedList<>()); + private final List subscriptionItems = Collections.synchronizedList(new ArrayList<>()); private ReceiveMsgHook callback; public CloudEventTCPSubClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { @@ -141,6 +142,7 @@ public void close() { } } + @Sharable private class CloudEventTCPSubHandler extends AbstractEventMeshTCPSubHandler { public CloudEventTCPSubHandler( @@ -160,8 +162,7 @@ public CloudEvent getProtocolMessage(Package tcpPackage) { public void callback(CloudEvent cloudEvent, ChannelHandlerContext ctx) { if (callback != null) { callback.handle(cloudEvent).ifPresent( - responseMessage -> ctx.writeAndFlush(MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER)) - ); + responseMessage -> ctx.writeAndFlush(MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER))); } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPPubClient.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPPubClient.java index 28b2d61b59..3d6af79e55 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPPubClient.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPPubClient.java @@ -79,9 +79,7 @@ public void reconnect() throws EventMeshException { public Package rr(EventMeshMessage eventMeshMessage, long timeout) throws EventMeshException { try { Package msg = MessageUtils.buildPackage(eventMeshMessage, Command.REQUEST_TO_SERVER); - if (log.isInfoEnabled()) { - log.info("{}|rr|send|type={}|msg={}", CLIENTNO, msg, msg); - } + log.info("{}|rr|send|type={}|msg={}", CLIENTNO, msg, msg); return io(msg, timeout); } catch (Exception e) { throw new EventMeshException("rr error", e); @@ -151,10 +149,8 @@ public EventMeshTCPPubHandler(ConcurrentHashMap contexts public void callback(EventMeshMessage eventMeshMessage, ChannelHandlerContext ctx) { if (callback != null) { callback.handle(eventMeshMessage).ifPresent( - responseMessage -> - ctx.writeAndFlush( - MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER)) - ); + responseMessage -> ctx.writeAndFlush( + MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER))); } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPSubClient.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPSubClient.java index dc159e1e13..7216597d7d 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPSubClient.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/tcp/impl/eventmeshmessage/EventMeshMessageTCPSubClient.java @@ -36,8 +36,8 @@ import org.apache.commons.collections4.CollectionUtils; +import java.util.ArrayList; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -48,7 +48,7 @@ @Slf4j class EventMeshMessageTCPSubClient extends TcpClient implements EventMeshTCPSubClient { - private final List subscriptionItems = Collections.synchronizedList(new LinkedList<>()); + private final List subscriptionItems = Collections.synchronizedList(new ArrayList<>()); private ReceiveMsgHook callback; public EventMeshMessageTCPSubClient(EventMeshTCPClientConfig eventMeshTcpClientConfig) { @@ -117,7 +117,6 @@ public void listen() throws EventMeshException { } } - @Override public void registerBusiHandler(ReceiveMsgHook receiveMsgHook) throws EventMeshException { this.callback = receiveMsgHook; @@ -147,8 +146,7 @@ public EventMeshMessage getProtocolMessage(Package tcpPackage) { public void callback(EventMeshMessage eventMeshMessage, ChannelHandlerContext ctx) { if (callback != null) { callback.handle(eventMeshMessage).ifPresent( - responseMessage -> ctx.writeAndFlush(MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER)) - ); + responseMessage -> ctx.writeAndFlush(MessageUtils.buildPackage(responseMessage, Command.RESPONSE_TO_SERVER))); } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/workflow/EventMeshWorkflowClient.java b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/workflow/EventMeshWorkflowClient.java index 8f8f4602d0..9a8e1fd8bc 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/workflow/EventMeshWorkflowClient.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/workflow/EventMeshWorkflowClient.java @@ -57,9 +57,7 @@ public WorkflowGrpc.WorkflowBlockingStub getWorkflowClient() throws Exception { public ExecuteResponse execute(final ExecuteRequest request) throws Exception { final WorkflowGrpc.WorkflowBlockingStub workflowClient = getWorkflowClient(); final ExecuteResponse response = workflowClient.execute(request); - if (log.isInfoEnabled()) { - log.info("received response:{}", response); - } + log.info("received response:{}", response); return response; } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumerTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumerTest.java index fa60200e88..508d841663 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumerTest.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/consumer/EventMeshGrpcConsumerTest.java @@ -25,38 +25,40 @@ 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.Constants; import org.apache.eventmesh.common.enums.EventMeshProtocolType; 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 org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.Builder; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.ConsumerServiceGrpc.ConsumerServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.ConsumerServiceGrpc.ConsumerServiceStub; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.HeartbeatServiceGrpc.HeartbeatServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.protocol.grpc.common.Response; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; 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.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import io.cloudevents.core.v1.CloudEventV1; 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.*"}) +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) public class EventMeshGrpcConsumerTest { @Mock @@ -67,24 +69,27 @@ public class EventMeshGrpcConsumerTest { private HeartbeatServiceBlockingStub heartbeatClient; private EventMeshGrpcConsumer eventMeshGrpcConsumer; - @Before + @BeforeEach public void setUp() { eventMeshGrpcConsumer = new EventMeshGrpcConsumer(EventMeshGrpcClientConfig.builder().build()); eventMeshGrpcConsumer.init(); eventMeshGrpcConsumer.setConsumerClient(consumerClient); eventMeshGrpcConsumer.setConsumerAsyncClient(consumerAsyncClient); eventMeshGrpcConsumer.setHeartbeatClient(heartbeatClient); - when(consumerClient.subscribe(any())).thenReturn(Response.getDefaultInstance()); - when(consumerClient.unsubscribe(any())).thenReturn(Response.getDefaultInstance()); - when(heartbeatClient.heartbeat(any())).thenReturn(Response.getDefaultInstance()); + when(consumerClient.subscribe(any())).thenReturn(CloudEvent.getDefaultInstance()); + when(consumerClient.unsubscribe(any())).thenReturn(CloudEvent.getDefaultInstance()); + when(heartbeatClient.heartbeat(any())).thenReturn(CloudEvent.getDefaultInstance()); when(consumerAsyncClient.subscribeStream(any())).thenAnswer(invocation -> { - StreamObserver receiver = invocation.getArgument(0); - return new StreamObserver() { + 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()); + public void onNext(CloudEvent value) { + Builder builder = CloudEvent.newBuilder(value) + .putAttributes(ProtocolKey.UNIQUE_ID, CloudEventAttributeValue.newBuilder().setCeString("1").build()) + .putAttributes(ProtocolKey.SEQ_NUM, CloudEventAttributeValue.newBuilder().setCeString("1").build()) + .setTextData("mockContent"); + receiver.onNext(builder.build()); receiver.onCompleted(); } @@ -102,12 +107,12 @@ public void onCompleted() { @Test public void testSubscribeWithUrl() { - assertThat(eventMeshGrpcConsumer.subscribe(Collections.singletonList(buildMockSubscriptionItem()), - "customUrl")).isEqualTo(Response.getDefaultInstance()); + assertThat(eventMeshGrpcConsumer.subscribe(Collections.singletonList(buildMockSubscriptionItem()), "customUrl")).isEqualTo( + Response.builder().build()); verify(consumerClient, times(1)).subscribe(any()); verify(heartbeatClient, Mockito.after(20_000L).times(1)).heartbeat(any()); - assertThat(eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(buildMockSubscriptionItem()), - "customUrl")).isEqualTo(Response.getDefaultInstance()); + assertThat(eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(buildMockSubscriptionItem()), "customUrl")).isEqualTo( + Response.builder().build()); verify(consumerClient, times(1)).unsubscribe(any()); } @@ -121,6 +126,7 @@ public void testSubscribeStreamWithoutListener() { public void testSubscribeStream() { List result = new ArrayList<>(); eventMeshGrpcConsumer.registerListener(new ReceiveMsgHook() { + @Override public Optional handle(Object msg) { result.add(msg); @@ -129,19 +135,18 @@ public Optional handle(Object msg) { @Override public EventMeshProtocolType getProtocolType() { - return EventMeshProtocolType.EVENT_MESH_MESSAGE; + return EventMeshProtocolType.CLOUD_EVENTS; } }); eventMeshGrpcConsumer.subscribe(Collections.singletonList(buildMockSubscriptionItem())); - assertThat(eventMeshGrpcConsumer.getSubscriptionMap().size()).isEqualTo(1); + assertThat(eventMeshGrpcConsumer.getSubscriptionMap()).hasSize(1); - assertThat(result).hasSize(1).first().isInstanceOf(EventMeshMessage.class) - .hasFieldOrPropertyWithValue("bizSeqNo", "1").hasFieldOrPropertyWithValue("uniqueId", "uniqueId") - .hasFieldOrPropertyWithValue("topic", "mockTopic") - .hasFieldOrPropertyWithValue("content", "mockContent"); + assertThat(result).hasSize(1).first().isInstanceOf(CloudEventV1.class); + CloudEventV1 v1 = (CloudEventV1) result.get(0); + Assertions.assertEquals(new String(v1.getData().toBytes(), Constants.DEFAULT_CHARSET), "mockContent"); verify(consumerAsyncClient, times(1)).subscribeStream(any()); assertThat(eventMeshGrpcConsumer.unsubscribe(Collections.singletonList(buildMockSubscriptionItem()))).isEqualTo( - Response.getDefaultInstance()); + Response.builder().build()); verify(consumerClient, times(1)).unsubscribe(any()); } @@ -152,13 +157,4 @@ private SubscriptionItem buildMockSubscriptionItem() { subscriptionItem.setTopic("topic"); return subscriptionItem; } - - @Test - public void testBuildSubscription() { - List subscriptionItems = new ArrayList<>(); - subscriptionItems.add(buildMockSubscriptionItem()); - subscriptionItems.add(buildMockSubscriptionItem()); - Subscription subsription = eventMeshGrpcConsumer.buildSubscription(subscriptionItems, "test_url"); - Assert.assertEquals(1, subsription.getSubscriptionItemsList().size()); - } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducerTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducerTest.java index a4af6e642a..dcfecbff52 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducerTest.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/CloudEventProducerTest.java @@ -21,60 +21,38 @@ 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 org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.common.Response; import java.util.Collections; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; 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 org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; -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.*"}) +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) public class CloudEventProducerTest { private CloudEventProducer cloudEventProducer; @Mock private PublisherServiceBlockingStub blockingStub; + @Mock - private Response mockResponse; + private CloudEvent mockCloudEvent; - @Before + @BeforeEach 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()); + when(blockingStub.batchPublish(Mockito.isA(CloudEventBatch.class))).thenReturn(mockCloudEvent); + when(blockingStub.publish(Mockito.isA(CloudEvent.class))).thenReturn(mockCloudEvent); } @Test @@ -84,11 +62,11 @@ public void testPublishMultiWithEmpty() { @Test public void testPublishMulti() { - assertThat(cloudEventProducer.publish(Collections.singletonList(new MockCloudEvent()))).isEqualTo(mockResponse); + assertThat(cloudEventProducer.publish(Collections.singletonList(new MockCloudEvent()))).isEqualTo(Response.builder().build()); } @Test public void testPublishSingle() { - assertThat(cloudEventProducer.publish(new MockCloudEvent())).isEqualTo(mockResponse); + assertThat(cloudEventProducer.publish(new MockCloudEvent())).isEqualTo(Response.builder().build()); } -} \ No newline at end of file +} diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducerTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducerTest.java index e3050a1c4f..afc4ba2103 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducerTest.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshGrpcProducerTest.java @@ -18,6 +18,7 @@ package org.apache.eventmesh.client.grpc.producer; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.argThat; @@ -30,29 +31,27 @@ 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.eventmesh.common.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.Response; 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.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; 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.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; -import io.cloudevents.CloudEvent; - -@RunWith(PowerMockRunner.class) -@PrepareForTest(PublisherServiceBlockingStub.class) -@PowerMockIgnore({"javax.management.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"}) +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) public class EventMeshGrpcProducerTest { private EventMeshGrpcProducer producer; @@ -64,7 +63,7 @@ public class EventMeshGrpcProducerTest { @Mock private EventMeshMessageProducer eventMeshMessageProducer; - @Before + @BeforeEach public void setUp() throws Exception { producer = new EventMeshGrpcProducer(EventMeshGrpcClientConfig.builder().build()); producer.setCloudEventProducer(cloudEventProducer); @@ -72,24 +71,17 @@ public void setUp() throws Exception { producer.setPublisherClient(stub); doThrow(RuntimeException.class).when(stub).publish( - argThat(argument -> argument != null && StringUtils.equals(argument.getContent(), + argThat(argument -> argument != null && StringUtils.equals(EventMeshCloudEventUtils.getDataContent(argument), "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"))); + doReturn(CloudEvent.getDefaultInstance()).when(stub).publish( + argThat(argument -> argument != null && StringUtils.equals(EventMeshCloudEventUtils.getDataContent(argument), "mockContent"))); + doReturn(CloudEvent.getDefaultInstance()).when(stub).batchPublish( + argThat(argument -> argument != null && StringUtils.equals(EventMeshCloudEventUtils.getSubject(argument.getEvents(0)), "mockTopic"))); doReturn(stub).when(stub).withDeadlineAfter(1000L, TimeUnit.MILLISECONDS); - doAnswer(invocation -> { - SimpleMessage simpleMessage = invocation.getArgument(0); - if (StringUtils.isEmpty(simpleMessage.getContent())) { - return SimpleMessage.getDefaultInstance(); - } - return SimpleMessage.newBuilder(simpleMessage).build(); - }).when(stub).requestReply(Mockito.isA(SimpleMessage.class)); - when(cloudEventProducer.publish(anyList())).thenReturn(Response.getDefaultInstance()); - when(cloudEventProducer.publish(Mockito.isA(CloudEvent.class))).thenReturn(Response.getDefaultInstance()); - when(eventMeshMessageProducer.publish(anyList())).thenReturn(Response.getDefaultInstance()); - when(eventMeshMessageProducer.publish(Mockito.isA(EventMeshMessage.class))).thenReturn(Response.getDefaultInstance()); + when(cloudEventProducer.publish(anyList())).thenReturn(Response.builder().build()); + when(cloudEventProducer.publish(Mockito.isA(io.cloudevents.CloudEvent.class))).thenReturn(Response.builder().build()); + when(eventMeshMessageProducer.publish(anyList())).thenReturn(Response.builder().build()); + when(eventMeshMessageProducer.publish(Mockito.isA(EventMeshMessage.class))).thenReturn(Response.builder().build()); doAnswer(invocation -> { EventMeshMessage eventMeshMessage = invocation.getArgument(0); if (StringUtils.isEmpty(eventMeshMessage.getContent())) { @@ -102,16 +94,12 @@ public void setUp() throws Exception { @Test public void testPublishWithException() { - try { - producer.publish(defaultEventMeshMessageBuilder().content("mockExceptionContent").build()); - } catch (Exception e) { - assertThat(e).isNotNull(); - } + assertThrows(IllegalArgumentException.class, () -> producer.publish("Not a supported message")); } @Test public void testPublishEventMeshMessage() { - assertThat(producer.publish(defaultEventMeshMessageBuilder().build())).isEqualTo(Response.getDefaultInstance()); + assertThat(producer.publish(defaultEventMeshMessageBuilder().build())).isEqualTo(Response.builder().build()); } @Test @@ -122,11 +110,11 @@ public void testPublishEmptyList() { @Test public void testPublishGenericMessageList() { assertThat(producer.publish(Collections.singletonList(new MockCloudEvent()))).isEqualTo( - Response.getDefaultInstance()); + Response.builder().build()); EventMeshMessageBuilder eventMeshMessageBuilder = defaultEventMeshMessageBuilder(); eventMeshMessageBuilder.prop(Collections.singletonMap(Constants.EVENTMESH_MESSAGE_CONST_TTL, "1000")); assertThat(producer.publish(Collections.singletonList(eventMeshMessageBuilder.build()))).isEqualTo( - Response.getDefaultInstance()); + Response.builder().build()); } @Test diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshMessageProducerTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshMessageProducerTest.java index fcdbca10eb..c31b4fcfb1 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshMessageProducerTest.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/producer/EventMeshMessageProducerTest.java @@ -25,10 +25,11 @@ import org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; import org.apache.eventmesh.common.EventMeshMessage; -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.protocol.grpc.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.PublisherServiceGrpc.PublisherServiceBlockingStub; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.Response; import org.apache.commons.lang3.StringUtils; @@ -37,18 +38,17 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; 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.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; -@RunWith(PowerMockRunner.class) -@PrepareForTest({PublisherServiceBlockingStub.class, Response.class}) -@PowerMockIgnore({"javax.management.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"}) +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) public class EventMeshMessageProducerTest { private EventMeshMessageProducer eventMeshMessageProducer; @@ -57,23 +57,20 @@ public class EventMeshMessageProducerTest { private PublisherServiceBlockingStub blockingStub; @Mock - private Response mockResponse; + private CloudEvent mockCloudEvent; - @Mock - private SimpleMessage mockSimpleMessage; - - @Before + @BeforeEach public void setUp() throws Exception { eventMeshMessageProducer = new EventMeshMessageProducer(EventMeshGrpcClientConfig.builder().build(), blockingStub); - when(blockingStub.batchPublish(Mockito.isA(BatchMessage.class))).thenReturn(mockResponse); - when(blockingStub.publish(Mockito.isA(SimpleMessage.class))).thenReturn(mockResponse); - when(blockingStub.requestReply(Mockito.isA(SimpleMessage.class))).thenReturn(mockSimpleMessage); + when(blockingStub.batchPublish(Mockito.isA(CloudEventBatch.class))).thenReturn(mockCloudEvent); + when(blockingStub.publish(Mockito.isA(CloudEvent.class))).thenReturn(mockCloudEvent); + when(blockingStub.requestReply(Mockito.isA(CloudEvent.class))).thenReturn(mockCloudEvent); doAnswer(invocation -> { - SimpleMessage simpleMessage = invocation.getArgument(0); - if (StringUtils.isEmpty(simpleMessage.getContent())) { - return SimpleMessage.getDefaultInstance(); + CloudEvent cloudEvent = invocation.getArgument(0); + if (StringUtils.isEmpty(EventMeshCloudEventUtils.getDataContent(cloudEvent))) { + return CloudEvent.getDefaultInstance(); } - return SimpleMessage.newBuilder(simpleMessage).build(); + return CloudEvent.newBuilder(cloudEvent).build(); }).when(blockingStub).requestReply(any()); doReturn(blockingStub).when(blockingStub).withDeadlineAfter(1000, TimeUnit.MILLISECONDS); } @@ -87,7 +84,7 @@ public void testPublishSingle() { .bizSeqNo("mxsm") .uniqueId("mxsm") .build(); - assertThat(eventMeshMessageProducer.publish(eventMeshMessage)).isEqualTo(mockResponse); + assertThat(eventMeshMessageProducer.publish(eventMeshMessage)).isEqualTo(Response.builder().build()); } @Test @@ -103,7 +100,7 @@ public void testPublishMulti() { .build(); messageArrayList.add(eventMeshMessage); } - assertThat(eventMeshMessageProducer.publish(messageArrayList)).isEqualTo(mockResponse); + assertThat(eventMeshMessageProducer.publish(messageArrayList)).isEqualTo(Response.builder().build()); assertThat(eventMeshMessageProducer.publish(Collections.emptyList())).isNull(); } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtilTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtilTest.java deleted file mode 100644 index b7e6218864..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/util/EventMeshClientUtilTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.client.grpc.util; - -import static org.assertj.core.api.Assertions.assertThat; - -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.enums.EventMeshProtocolType; -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 java.util.Objects; - -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, EventMeshProtocolType.CLOUD_EVENTS)).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", EventMeshProtocolType.CLOUD_EVENTS.protocolTypeName()) - .hasFieldOrPropertyWithValue("protocolDesc", Constants.PROTOCOL_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, EventMeshProtocolType.CLOUD_EVENTS); - 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, EventMeshProtocolType.EVENT_MESH_MESSAGE); - 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, - EventMeshProtocolType.CLOUD_EVENTS)).hasFieldOrPropertyWithValue("header", - EventMeshClientUtil.buildHeader(clientConfig, EventMeshProtocolType.CLOUD_EVENTS)) - .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( - Objects.requireNonNull(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, EventMeshProtocolType.EVENT_MESH_MESSAGE)) - .hasFieldOrPropertyWithValue("header", EventMeshClientUtil.buildHeader(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE)) - .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, - EventMeshProtocolType.CLOUD_EVENTS); - assertThat(batchMessage).hasFieldOrPropertyWithValue("header", - EventMeshClientUtil.buildHeader(clientConfig, EventMeshProtocolType.CLOUD_EVENTS)) - .hasFieldOrPropertyWithValue("topic", cloudEvents.get(0).getSubject()) - .hasFieldOrPropertyWithValue("producerGroup", clientConfig.getProducerGroup()); - assertThat(batchMessage.getMessageItemList()).hasSize(1).first().hasFieldOrPropertyWithValue("content", - new String(Objects.requireNonNull(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, EventMeshProtocolType.EVENT_MESH_MESSAGE); - assertThat(batchMessage).hasFieldOrPropertyWithValue("header", - EventMeshClientUtil.buildHeader(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE)) - .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)); - } -} diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/util/EventMeshCloudEventBuilderTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/util/EventMeshCloudEventBuilderTest.java new file mode 100644 index 0000000000..1b1de0a191 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/grpc/util/EventMeshCloudEventBuilderTest.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 org.apache.eventmesh.client.grpc.config.EventMeshGrpcClientConfig; +import org.apache.eventmesh.common.EventMeshMessage; +import org.apache.eventmesh.common.enums.EventMeshProtocolType; +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.cloudevents.CloudEvent; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEvent.CloudEventAttributeValue; +import org.apache.eventmesh.common.protocol.grpc.cloudevents.CloudEventBatch; +import org.apache.eventmesh.common.protocol.grpc.common.EventMeshCloudEventUtils; +import org.apache.eventmesh.common.protocol.grpc.common.ProtocolKey; +import org.apache.eventmesh.common.utils.JsonUtils; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import io.cloudevents.core.builder.CloudEventBuilder; + +public class EventMeshCloudEventBuilderTest { + + private EventMeshGrpcClientConfig clientConfig; + + @BeforeEach + public void init() { + clientConfig = EventMeshGrpcClientConfig.builder().build(); + } + + @Test + public void testBuildCommonCloudEventAttributes() { + + Map attributeValueMap = EventMeshCloudEventBuilder.buildCommonCloudEventAttributes( + clientConfig, EventMeshProtocolType.CLOUD_EVENTS); + Assertions.assertNotNull(attributeValueMap); + Assertions.assertEquals(EventMeshProtocolType.CLOUD_EVENTS.protocolTypeName(), + attributeValueMap.get(ProtocolKey.PROTOCOL_TYPE).getCeString()); + Map attributeValueMap1 = EventMeshCloudEventBuilder.buildCommonCloudEventAttributes( + clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE); + Assertions.assertNotNull(attributeValueMap1); + Assertions.assertEquals(EventMeshProtocolType.EVENT_MESH_MESSAGE.protocolTypeName(), + attributeValueMap1.get(ProtocolKey.PROTOCOL_TYPE).getCeString()); + Map attributeValueMap2 = EventMeshCloudEventBuilder.buildCommonCloudEventAttributes( + clientConfig, EventMeshProtocolType.OPEN_MESSAGE); + Assertions.assertNotNull(attributeValueMap2); + Assertions.assertEquals(EventMeshProtocolType.OPEN_MESSAGE.protocolTypeName(), + attributeValueMap2.get(ProtocolKey.PROTOCOL_TYPE).getCeString()); + + } + + @Test + public void testBuildEventSubscription() { + List subscriptionItems = new ArrayList<>(); + for (int i = 0; i < 5; ++i) { + SubscriptionItem item = new SubscriptionItem(); + item.setMode(i % 2 == 0 ? SubscriptionMode.CLUSTERING : SubscriptionMode.BROADCASTING); + item.setTopic("mxsm" + i); + item.setType(i % 2 == 1 ? SubscriptionType.SYNC : SubscriptionType.ASYNC); + subscriptionItems.add(item); + } + CloudEvent cloudEvent = EventMeshCloudEventBuilder.buildEventSubscription(clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE, "127.0.0.1", + subscriptionItems); + Assertions.assertNotNull(cloudEvent); + } + + @Test + public void testBuildEventMeshCloudEvent() { + String id = UUID.randomUUID().toString(); + io.cloudevents.CloudEvent event = + CloudEventBuilder.v1().withType("eventmesh").withSource(URI.create("/")).withId(id).build(); + EventMeshMessage meshMessage = EventMeshMessage.builder().build(); + Assertions.assertThrows(Exception.class, + () -> EventMeshCloudEventBuilder.buildEventMeshCloudEvent(event, clientConfig, EventMeshProtocolType.EVENT_MESH_MESSAGE)); + CloudEvent cloudEvent = EventMeshCloudEventBuilder.buildEventMeshCloudEvent(event, clientConfig, EventMeshProtocolType.CLOUD_EVENTS); + Assertions.assertNotNull(cloudEvent); + Assertions.assertEquals("eventmesh", cloudEvent.getType()); + Assertions.assertEquals(id, cloudEvent.getId()); + Assertions.assertThrows(Exception.class, + () -> EventMeshCloudEventBuilder.buildEventMeshCloudEvent(meshMessage, clientConfig, EventMeshProtocolType.CLOUD_EVENTS)); + EventMeshMessage meshMessage1 = EventMeshMessage.builder().uniqueId(id).build(); + CloudEvent cloudEvent1 = EventMeshCloudEventBuilder.buildEventMeshCloudEvent(meshMessage1, clientConfig, + EventMeshProtocolType.EVENT_MESH_MESSAGE); + Assertions.assertNotNull(cloudEvent1); + Assertions.assertEquals("org.apache.eventmesh", cloudEvent1.getType()); + Assertions.assertEquals(id, EventMeshCloudEventUtils.getUniqueId(cloudEvent1)); + + } + + @Test + public void testBuildEventMeshCloudEventBatch() { + List cloudEventList = new ArrayList<>(); + CloudEventBatch cloudEventBatch = EventMeshCloudEventBuilder.buildEventMeshCloudEventBatch(cloudEventList, clientConfig, + EventMeshProtocolType.CLOUD_EVENTS); + Assertions.assertNull(cloudEventBatch); + CloudEventBatch cloudEventBatch1 = EventMeshCloudEventBuilder.buildEventMeshCloudEventBatch(null, clientConfig, + EventMeshProtocolType.CLOUD_EVENTS); + Assertions.assertNull(cloudEventBatch1); + List cloudEventList2 = new ArrayList<>(); + for (int i = 0; i < 3; ++i) { + String id = UUID.randomUUID().toString(); + io.cloudevents.CloudEvent event = + CloudEventBuilder.v1().withType("eventmesh" + i).withSource(URI.create("/")).withId(id).build(); + cloudEventList2.add(event); + } + CloudEventBatch cloudEventBatch2 = EventMeshCloudEventBuilder.buildEventMeshCloudEventBatch(cloudEventList2, clientConfig, + EventMeshProtocolType.CLOUD_EVENTS); + Assertions.assertNotNull(cloudEventBatch2); + + List messageList = new ArrayList<>(); + for (int i = 0; i < 3; ++i) { + EventMeshMessage meshMessage1 = EventMeshMessage.builder().uniqueId(UUID.randomUUID().toString()).build(); + messageList.add(meshMessage1); + } + CloudEventBatch cloudEventBatch3 = EventMeshCloudEventBuilder.buildEventMeshCloudEventBatch(messageList, clientConfig, + EventMeshProtocolType.EVENT_MESH_MESSAGE); + Assertions.assertNotNull(cloudEventBatch3); + Assertions.assertEquals(3, cloudEventBatch3.getEventsCount()); + } + + @Test + public void testBuildMessageFromEventMeshCloudEvent() { + + Object object = EventMeshCloudEventBuilder.buildMessageFromEventMeshCloudEvent(null, EventMeshProtocolType.CLOUD_EVENTS); + Assertions.assertNull(object); + CloudEvent eventmesh = CloudEvent.newBuilder().setSpecVersion("1.0").setType("eventmesh").setSource(URI.create("/").toString()) + .setId(UUID.randomUUID().toString()).build(); + Object event = EventMeshCloudEventBuilder.buildMessageFromEventMeshCloudEvent(eventmesh, EventMeshProtocolType.CLOUD_EVENTS); + Assertions.assertNull(event); + CloudEvent eventmesh1 = CloudEvent.newBuilder().setSpecVersion("1.0").setType("eventmesh").setSource(URI.create("/").toString()) + .setId(UUID.randomUUID().toString()).putAttributes(ProtocolKey.SEQ_NUM, CloudEventAttributeValue.newBuilder().setCeString("1").build()) + .build(); + Object event1 = EventMeshCloudEventBuilder.buildMessageFromEventMeshCloudEvent(eventmesh1, EventMeshProtocolType.CLOUD_EVENTS); + Assertions.assertTrue(event1 instanceof io.cloudevents.CloudEvent); + Object event2 = EventMeshCloudEventBuilder.buildMessageFromEventMeshCloudEvent(eventmesh1, EventMeshProtocolType.EVENT_MESH_MESSAGE); + Assertions.assertTrue(event2 instanceof EventMeshMessage); + + final Map attributeValueMap = EventMeshCloudEventBuilder.buildCommonCloudEventAttributes(clientConfig, + EventMeshProtocolType.EVENT_MESH_MESSAGE); + attributeValueMap.put(ProtocolKey.CONSUMERGROUP, CloudEventAttributeValue.newBuilder().setCeString(clientConfig.getConsumerGroup()).build()); + attributeValueMap.put(ProtocolKey.DATA_CONTENT_TYPE, CloudEventAttributeValue.newBuilder().setCeString("application/json").build()); + Set set = new HashSet<>(); + SubscriptionItem subscriptionItem = new SubscriptionItem("111", SubscriptionMode.CLUSTERING, SubscriptionType.SYNC); + set.add(subscriptionItem); + CloudEvent eventmesh2 = CloudEvent.newBuilder().setSpecVersion("1.0").setType("eventmesh").setSource(URI.create("/").toString()) + .setId(UUID.randomUUID().toString()).putAllAttributes(attributeValueMap).setTextData(JsonUtils.toJSONString(set)).build(); + Object event4 = EventMeshCloudEventBuilder.buildMessageFromEventMeshCloudEvent(eventmesh2, EventMeshProtocolType.CLOUD_EVENTS); + Assertions.assertTrue(event4 instanceof Set); + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncPublishInstance.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncPublishInstance.java index 2387020a5b..403c3d13be 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncPublishInstance.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncPublishInstance.java @@ -27,7 +27,6 @@ import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncSyncRequestInstance.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncSyncRequestInstance.java index 01b1e6a5ae..5ef236acb1 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncSyncRequestInstance.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/AsyncSyncRequestInstance.java @@ -17,7 +17,6 @@ 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; @@ -30,7 +29,6 @@ import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -40,9 +38,9 @@ public static void main(String[] args) throws Exception { EventMeshHttpProducer eventMeshHttpProducer = null; try { - //String eventMeshIPPort = args[0]; + // String eventMeshIPPort = args[0]; String eventMeshIPPort = ""; - //final String topic = args[1]; + // 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 @@ -68,10 +66,11 @@ public static void main(String[] args) throws Exception { .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); + log.debug("sendmsg: {}, return: {}, cost: {}ms", + eventMeshMessage.getContent(), o.getContent(), System.currentTimeMillis() - startTime); } @Override diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/SyncRequestInstance.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/SyncRequestInstance.java index 3d2c10bab2..baf31566de 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/SyncRequestInstance.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/demo/SyncRequestInstance.java @@ -28,7 +28,6 @@ import java.util.concurrent.TimeUnit; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -66,10 +65,7 @@ public static void main(String[] args) throws Exception { .uniqueId(RandomStringUtils.generateNum(30)).build(); EventMeshMessage rsp = eventMeshHttpProducer.request(eventMeshMessage, 10000); - if (log.isDebugEnabled()) { - log.debug("sendmsg : {}, return : {}, cost:{}ms", eventMeshMessage.getContent(), rsp.getContent(), - System.currentTimeMillis() - startTime); - } + log.debug("sendmsg: {}, return: {}, cost:{}ms", eventMeshMessage.getContent(), rsp.getContent(), System.currentTimeMillis() - startTime); } catch (Exception e) { log.warn("send msg failed", e); } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtilsTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtilsTest.java index ecc8b9aa7a..fc80ccf731 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtilsTest.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpLoadBalanceUtilsTest.java @@ -22,8 +22,8 @@ import org.apache.eventmesh.common.loadbalance.LoadBalanceSelector; import org.apache.eventmesh.common.loadbalance.LoadBalanceType; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class HttpLoadBalanceUtilsTest { @@ -34,7 +34,7 @@ public void testCreateRandomSelector() throws EventMeshException { .build(); LoadBalanceSelector randomSelector = HttpLoadBalanceUtils .createEventMeshServerLoadBalanceSelector(eventMeshHttpClientConfig); - Assert.assertEquals(LoadBalanceType.RANDOM, randomSelector.getType()); + Assertions.assertEquals(LoadBalanceType.RANDOM, randomSelector.getType()); } @Test @@ -44,7 +44,7 @@ public void testCreateWeightRoundRobinSelector() throws EventMeshException { .loadBalanceType(LoadBalanceType.WEIGHT_ROUND_ROBIN).build(); LoadBalanceSelector weightRoundRobinSelector = HttpLoadBalanceUtils .createEventMeshServerLoadBalanceSelector(eventMeshHttpClientConfig); - Assert.assertEquals(LoadBalanceType.WEIGHT_ROUND_ROBIN, weightRoundRobinSelector.getType()); + Assertions.assertEquals(LoadBalanceType.WEIGHT_ROUND_ROBIN, weightRoundRobinSelector.getType()); } @Test @@ -54,6 +54,6 @@ public void testCreateWeightRandomSelector() throws EventMeshException { .loadBalanceType(LoadBalanceType.WEIGHT_RANDOM).build(); LoadBalanceSelector weightRoundRobinSelector = HttpLoadBalanceUtils .createEventMeshServerLoadBalanceSelector(eventMeshHttpClientConfig); - Assert.assertEquals(LoadBalanceType.WEIGHT_RANDOM, weightRoundRobinSelector.getType()); + Assertions.assertEquals(LoadBalanceType.WEIGHT_RANDOM, weightRoundRobinSelector.getType()); } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpUtilsTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpUtilsTest.java index 9d6cc472a8..ce65270297 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpUtilsTest.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/http/util/HttpUtilsTest.java @@ -17,7 +17,6 @@ package org.apache.eventmesh.client.http.util; - import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -31,75 +30,52 @@ import java.io.IOException; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import io.netty.handler.codec.http.HttpMethod; public class HttpUtilsTest { - @Test - public void testPostPositive() { + public void testPostPositive() throws IOException { CloseableHttpClient client = mock(CloseableHttpClient.class); String uri = "http://example.com"; RequestParam requestParam = new RequestParam(HttpMethod.POST); - IOException exception = null; - try { - String expectedResult = "Success"; - when(client.execute(any(HttpPost.class), any(ResponseHandler.class))).thenReturn(expectedResult); - String result = HttpUtils.post(client, uri, requestParam); - Assert.assertEquals(expectedResult, result); - } catch (IOException e) { - exception = e; - } - Assert.assertNull(exception); + String expectedResult = "Success"; + when(client.execute(any(HttpPost.class), any(ResponseHandler.class))).thenReturn(expectedResult); + String result = HttpUtils.post(client, uri, requestParam); + Assertions.assertEquals(expectedResult, result); } @Test - public void testPostNegative() { + public void testPostNegative() throws IOException { CloseableHttpClient client = mock(CloseableHttpClient.class); String uri = "http://example.com"; RequestParam requestParam = new RequestParam(HttpMethod.GET); String expectedResult = "Failure"; - try { - when(client.execute(any(HttpPost.class), any(ResponseHandler.class))).thenReturn(expectedResult); - String result = HttpUtils.post(client, uri, requestParam); - Assert.assertNotEquals(expectedResult, result); - } catch (Exception e) { - Assert.assertNotNull(e); - } + when(client.execute(any(HttpPost.class), any(ResponseHandler.class))).thenReturn(expectedResult); + Assertions.assertThrows(Exception.class, () -> HttpUtils.post(client, uri, requestParam)); } @Test - public void testGetPositive() { + public void testGetPositive() throws IOException { CloseableHttpClient client = mock(CloseableHttpClient.class); String uri = "http://example.com"; RequestParam requestParam = new RequestParam(HttpMethod.GET); String expectedResult = "Success"; - IOException exception = null; - try { - when(client.execute(any(HttpGet.class), any(ResponseHandler.class))).thenReturn(expectedResult); - String result = HttpUtils.get(client, uri, requestParam); - Assert.assertEquals(expectedResult, result); - } catch (IOException e) { - exception = e; - } - Assert.assertNull(exception); + when(client.execute(any(HttpGet.class), any(ResponseHandler.class))).thenReturn(expectedResult); + String result = HttpUtils.get(client, uri, requestParam); + Assertions.assertEquals(expectedResult, result); } @Test - public void testGetNegative() { + public void testGetNegative() throws IOException { CloseableHttpClient client = mock(CloseableHttpClient.class); String uri = "http://example.com"; RequestParam requestParam = new RequestParam(HttpMethod.POST); String expectedResult = "Failure"; - try { - when(client.execute(any(HttpGet.class), any(ResponseHandler.class))).thenReturn(expectedResult); - String result = HttpUtils.get(client, uri, requestParam); - Assert.assertNotEquals(expectedResult, result); - } catch (Exception e) { - Assert.assertNotNull(e); - } + when(client.execute(any(HttpGet.class), any(ResponseHandler.class))).thenReturn(expectedResult); + Assertions.assertThrows(Exception.class, () -> HttpUtils.get(client, uri, requestParam)); } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestCaseTopicSet.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestCaseTopicSet.java index 669e598a8c..f340e93bd5 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestCaseTopicSet.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestCaseTopicSet.java @@ -22,13 +22,13 @@ */ public class EventMeshTestCaseTopicSet { - // public static final String TOPIC_PRX_WQ2ClientBroadCast = "topic-broadcast-test"; + // 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 = "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 = "topic-async-test"; public static final String TOPIC_PRX_WQ2ClientUniCast = "TEST-TOPIC-TCP-ASYNC"; } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestUtils.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestUtils.java index aa7c808ab9..dbd3e7233b 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestUtils.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/EventMeshTestUtils.java @@ -108,7 +108,6 @@ public static EventMeshMessage generateSyncRRMqMsg() { return mqMsg; } - private static EventMeshMessage generateAsyncRRMqMsg() { EventMeshMessage mqMsg = new EventMeshMessage(); mqMsg.setTopic(TOPIC_PRX_SyncSubscribeTest); diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/MessageUtilsTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/MessageUtilsTest.java index d9f3406b9e..4916cf5612 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/MessageUtilsTest.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/common/MessageUtilsTest.java @@ -29,9 +29,8 @@ import java.util.UUID; -import org.junit.Assert; -import org.junit.Test; - +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class MessageUtilsTest { @@ -40,55 +39,48 @@ public void testHello() { // Positive Test Case UserAgent user = new UserAgent(); Package msg = MessageUtils.hello(user); - Assert.assertNotNull(msg); - Assert.assertEquals(msg.getHeader().getCommand(), Command.HELLO_REQUEST); - Assert.assertNotNull(msg.getBody()); - Assert.assertTrue(msg.getBody() instanceof UserAgent); + Assertions.assertNotNull(msg); + Assertions.assertEquals(Command.HELLO_REQUEST, msg.getHeader().getCommand()); + Assertions.assertNotNull(msg.getBody()); + Assertions.assertTrue(msg.getBody() instanceof UserAgent); // Negative Test Case - user = null; - try { - msg = null; - msg = MessageUtils.hello(user); - - } catch (Exception e) { - Assert.assertNull(msg); - } + Assertions.assertDoesNotThrow(() -> MessageUtils.hello(null)); } @Test public void testHeartBeat() { // Positive Test Case Package msg = MessageUtils.heartBeat(); - Assert.assertNotNull(msg); - Assert.assertEquals(msg.getHeader().getCommand(), Command.HEARTBEAT_REQUEST); - Assert.assertNull(msg.getBody()); + Assertions.assertNotNull(msg); + Assertions.assertEquals(Command.HEARTBEAT_REQUEST, msg.getHeader().getCommand()); + Assertions.assertNull(msg.getBody()); // Negative Test Case msg = null; - Assert.assertNull(msg); + Assertions.assertNull(msg); } @Test public void testGoodbye() { // Positive Test Case Package msg = MessageUtils.goodbye(); - Assert.assertNotNull(msg); - Assert.assertEquals(msg.getHeader().getCommand(), Command.CLIENT_GOODBYE_REQUEST); - Assert.assertNull(msg.getBody()); + Assertions.assertNotNull(msg); + Assertions.assertEquals(Command.CLIENT_GOODBYE_REQUEST, msg.getHeader().getCommand()); + Assertions.assertNull(msg.getBody()); // Negative Test Case msg = null; - Assert.assertNull(msg); + Assertions.assertNull(msg); } @Test public void testListen() { // Positive Test Case Package msg = MessageUtils.listen(); - Assert.assertNotNull(msg); - Assert.assertEquals(msg.getHeader().getCommand(), Command.LISTEN_REQUEST); - Assert.assertNull(msg.getBody()); + Assertions.assertNotNull(msg); + Assertions.assertEquals(Command.LISTEN_REQUEST, msg.getHeader().getCommand()); + Assertions.assertNull(msg.getBody()); // Negative Test Case msg = null; - Assert.assertNull(msg); + Assertions.assertNull(msg); } @Test @@ -98,33 +90,24 @@ public void testSubscribe() { SubscriptionMode subscriptionMode = SubscriptionMode.CLUSTERING; SubscriptionType subscriptionType = SubscriptionType.SYNC; Package msg = MessageUtils.subscribe(topic, subscriptionMode, subscriptionType); - Assert.assertNotNull(msg); - Assert.assertEquals(msg.getHeader().getCommand(), Command.SUBSCRIBE_REQUEST); - Assert.assertNotNull(msg.getBody()); - Assert.assertTrue(msg.getBody() instanceof Subscription); + Assertions.assertNotNull(msg); + Assertions.assertEquals(Command.SUBSCRIBE_REQUEST, msg.getHeader().getCommand()); + Assertions.assertNotNull(msg.getBody()); + Assertions.assertTrue(msg.getBody() instanceof Subscription); // Negative Test Case - topic = null; - subscriptionMode = null; - subscriptionType = null; - try { - msg = null; - msg = MessageUtils.subscribe(topic, subscriptionMode, subscriptionType); - - } catch (Exception e) { - Assert.assertNull(msg); - } + Assertions.assertDoesNotThrow(() -> MessageUtils.subscribe(null, null, null)); } @Test public void testUnsubscribe() { // Positive Test Case Package msg = MessageUtils.unsubscribe(); - Assert.assertNotNull(msg); - Assert.assertEquals(msg.getHeader().getCommand(), Command.UNSUBSCRIBE_REQUEST); - Assert.assertNull(msg.getBody()); + Assertions.assertNotNull(msg); + Assertions.assertEquals(Command.UNSUBSCRIBE_REQUEST, msg.getHeader().getCommand()); + Assertions.assertNull(msg.getBody()); // Negative Test Case msg = null; - Assert.assertNull(msg); + Assertions.assertNull(msg); } @Test @@ -135,19 +118,13 @@ public void testAsyncMessageAck() { in.setHeader(header); in.setBody("testBody"); Package msg = MessageUtils.asyncMessageAck(in); - Assert.assertNotNull(msg); - Assert.assertEquals(msg.getHeader().getCommand(), Command.ASYNC_MESSAGE_TO_CLIENT_ACK); - Assert.assertEquals(msg.getHeader().getSeq(), in.getHeader().getSeq()); - Assert.assertNotNull(msg.getBody()); - Assert.assertEquals(msg.getBody(), in.getBody()); + Assertions.assertNotNull(msg); + Assertions.assertEquals(Command.ASYNC_MESSAGE_TO_CLIENT_ACK, msg.getHeader().getCommand()); + Assertions.assertEquals(msg.getHeader().getSeq(), in.getHeader().getSeq()); + Assertions.assertNotNull(msg.getBody()); + Assertions.assertEquals(msg.getBody(), in.getBody()); // Negative Test Case - in = null; - msg = null; - try { - msg = MessageUtils.asyncMessageAck(in); - } catch (Exception e) { - Assert.assertNull(msg); - } + Assertions.assertThrows(Exception.class, () -> MessageUtils.asyncMessageAck(null)); } @Test @@ -157,11 +134,11 @@ public void testBuildPackage() { eventMeshMessage.setBody("111"); Command command = Command.ASYNC_MESSAGE_TO_SERVER; Package msg = MessageUtils.buildPackage(eventMeshMessage, command); - Assert.assertNotNull(msg); - Assert.assertEquals(msg.getHeader().getCommand(), command); - Assert.assertEquals(msg.getHeader().getProperty(Constants.PROTOCOL_TYPE), EventMeshCommon.EM_MESSAGE_PROTOCOL_NAME); - Assert.assertEquals(msg.getHeader().getProperty(Constants.PROTOCOL_DESC), "tcp"); - Assert.assertNotNull(msg.getBody()); - Assert.assertTrue(msg.getBody() instanceof EventMeshMessage); + Assertions.assertNotNull(msg); + Assertions.assertEquals(msg.getHeader().getCommand(), command); + Assertions.assertEquals(EventMeshCommon.EM_MESSAGE_PROTOCOL_NAME, msg.getHeader().getProperty(Constants.PROTOCOL_TYPE)); + Assertions.assertEquals("tcp", msg.getHeader().getProperty(Constants.PROTOCOL_DESC)); + Assertions.assertNotNull(msg.getBody()); + Assertions.assertTrue(msg.getBody() instanceof EventMeshMessage); } } diff --git a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/impl/EventMeshTCPClientFactoryTest.java b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/impl/EventMeshTCPClientFactoryTest.java index cc2f0bd175..c9510078f4 100644 --- a/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/impl/EventMeshTCPClientFactoryTest.java +++ b/eventmesh-sdks/eventmesh-sdk-java/src/test/java/org/apache/eventmesh/client/tcp/impl/EventMeshTCPClientFactoryTest.java @@ -25,8 +25,8 @@ 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 org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import io.cloudevents.CloudEvent; import io.openmessaging.api.Message; @@ -42,14 +42,14 @@ public void createEventMeshTCPClient() { EventMeshTCPClient eventMeshMessageTCPClient = EventMeshTCPClientFactory.createEventMeshTCPClient(meshTCPClientConfig, EventMeshMessage.class); - Assert.assertEquals(EventMeshMessageTCPClient.class, eventMeshMessageTCPClient.getClass()); + Assertions.assertEquals(EventMeshMessageTCPClient.class, eventMeshMessageTCPClient.getClass()); EventMeshTCPClient cloudEventTCPClient = EventMeshTCPClientFactory.createEventMeshTCPClient(meshTCPClientConfig, CloudEvent.class); - Assert.assertEquals(CloudEventTCPClient.class, cloudEventTCPClient.getClass()); + Assertions.assertEquals(CloudEventTCPClient.class, cloudEventTCPClient.getClass()); EventMeshTCPClient openMessageTCPClient = EventMeshTCPClientFactory.createEventMeshTCPClient(meshTCPClientConfig, Message.class); - Assert.assertEquals(OpenMessageTCPClient.class, openMessageTCPClient.getClass()); + Assertions.assertEquals(OpenMessageTCPClient.class, openMessageTCPClient.getClass()); } } diff --git a/eventmesh-sdks/eventmesh-sdk-rust/.gitignore b/eventmesh-sdks/eventmesh-sdk-rust/.gitignore index 01d6fe8975..593b689a59 100644 --- a/eventmesh-sdks/eventmesh-sdk-rust/.gitignore +++ b/eventmesh-sdks/eventmesh-sdk-rust/.gitignore @@ -1,2 +1,6 @@ +target +Cargo.lock +.git target/ -.vscode \ No newline at end of file +.vscode +.idea \ No newline at end of file diff --git a/eventmesh-sdks/eventmesh-sdk-rust/Cargo.lock b/eventmesh-sdks/eventmesh-sdk-rust/Cargo.lock deleted file mode 100644 index b1cb1cbb44..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/Cargo.lock +++ /dev/null @@ -1,1606 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] -name = "anyhow" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8" - -[[package]] -name = "async-stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-trait" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "axum" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de18bc5f2e9df8f52da03856bf40e29b747de5a84e43aefff90e3dc4a21529b" -dependencies = [ - "async-trait", - "axum-core", - "bitflags", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower", - "tower-http", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4f44a0e6200e9d11a1cdc989e4b358f6e3d354fbf48478f345a17f4e43f8635" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", -] - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bumpalo" -version = "3.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" - -[[package]] -name = "bytes" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "either" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" - -[[package]] -name = "encoding_rs" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "eventmesh" -version = "0.1.0" -dependencies = [ - "anyhow", - "futures", - "futures-util", - "prost", - "reqwest", - "serde", - "serde_json", - "tokio", - "tokio-stream", - "tonic", - "tonic-build", -] - -[[package]] -name = "examples" -version = "0.0.0" -dependencies = [ - "anyhow", - "axum", - "eventmesh", - "serde", - "serde_json", - "tokio", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" - -[[package]] -name = "futures-executor" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" - -[[package]] -name = "futures-macro" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" - -[[package]] -name = "futures-task" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" - -[[package]] -name = "futures-util" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "getrandom" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "h2" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "http" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "http-range-header" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" - -[[package]] -name = "httparse" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "hyper" -version = "0.14.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ipnet" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" - -[[package]] -name = "js-sys" -version = "0.3.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.131" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" - -[[package]] -name = "lock_api" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "matchit" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mio" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys", -] - -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - -[[package]] -name = "native-tls" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" - -[[package]] -name = "openssl" -version = "0.10.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "petgraph" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "pin-project" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" - -[[package]] -name = "ppv-lite86" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" - -[[package]] -name = "prettyplease" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697ae720ee02011f439e0701db107ffe2916d83f718342d65d7f8bf7b8a5fee9" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399c3c31cdec40583bb68f0b18403400d01ec4289c383aa047560439952c4dd7" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f835c582e6bd972ba8347313300219fed5bfa52caf175298d860b61ff6069bb" -dependencies = [ - "bytes", - "heck", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph", - "prost", - "prost-types", - "regex", - "tempfile", - "which", -] - -[[package]] -name = "prost-derive" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7345d5f0e08c0536d7ac7229952590239e77abf0a0100a1b1d890add6ea96364" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "prost-types" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dfaa718ad76a44b3415e6c4d53b17c8f99160dcb3a99b10470fce8ad43f6e3e" -dependencies = [ - "bytes", - "prost", -] - -[[package]] -name = "quote" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "reqwest" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "lazy_static", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "ryu" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" - -[[package]] -name = "schannel" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" -dependencies = [ - "lazy_static", - "windows-sys", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "security-framework" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.143" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.143" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "syn" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" -dependencies = [ - "autocfg", - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "once_cell", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "tonic" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "498f271adc46acce75d66f639e4d35b31b2394c295c82496727dafa16d465dd2" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost", - "prost-derive", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "tracing-futures", -] - -[[package]] -name = "tonic-build" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fbcd2800e34e743b9ae795867d5f77b535d3a3be69fd731e39145719752df8c" -dependencies = [ - "prettyplease", - "proc-macro2", - "prost-build", - "quote", - "syn", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" -dependencies = [ - "ansi_term", - "sharded-slab", - "smallvec", - "thread_local", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - -[[package]] -name = "unicode-bidi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" - -[[package]] -name = "unicode-ident" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" - -[[package]] -name = "unicode-normalization" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" - -[[package]] -name = "web-sys" -version = "0.3.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "which" -version = "4.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" -dependencies = [ - "either", - "lazy_static", - "libc", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] diff --git a/eventmesh-sdks/eventmesh-sdk-rust/Cargo.toml b/eventmesh-sdks/eventmesh-sdk-rust/Cargo.toml index 3c07c7b02e..0209e3d5e5 100644 --- a/eventmesh-sdks/eventmesh-sdk-rust/Cargo.toml +++ b/eventmesh-sdks/eventmesh-sdk-rust/Cargo.toml @@ -14,7 +14,73 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +# +[package] +name = "eventmesh" +version = "1.9.0" +edition = "2021" +authors = [ + "mxsm " +] +msrv = "1.75.0" +description = "Rust client for Apache EventMesh" +license = "Apache-2.0" +keywords = ["EventMesh", "SDK", "rust-client", "rust", "eventmesh-rust-sdk"] +readme = "./README.md" +homepage = "https://github.com/apache/eventmesh" +repository = "https://github.com/apache/eventmesh" + +[features] +default = ["grpc", "eventmesh_message"] +full = ["grpc", "eventmesh_message","cloud_events"] +eventmesh_message = [] +cloud_events = [] +tls = [] +grpc = [] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +# common +anyhow = "1.0" + +#Rust grpc +tonic = "0.10" +prost = "0.12" +prost-types = "0.12" + +#tokio +tokio = { version = "1.32.0", features = ["full"] } + +#serde +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" + +#log +tracing = "0.1" +tracing-subscriber = "0.3" + +#cloudEvents +cloudevents-sdk = "0.7.0" + +# tools crate +thiserror = "1.0" +bytes = "1" +rand = "0.8" +uuid = { version = "1.4.1", features = ["v4"] } +local-ip-address = "0.5.6" +futures = "0.3" +log = "0.4.20" +chrono = "0.4" + +[build-dependencies] +tonic-build = "0.10" + +[[example]] +name = "producer_example" +path = "examples/grpc/producer_example.rs" +required-features = ["grpc", "eventmesh_message","cloud_events"] -[workspace] -members = ["eventmesh", "examples"] -resolver = "2" +[[example]] +name = "consumer_example" +path = "examples/grpc/consumer_example.rs" +required-features = ["grpc", "eventmesh_message"] \ No newline at end of file diff --git a/eventmesh-sdks/eventmesh-sdk-rust/README.md b/eventmesh-sdks/eventmesh-sdk-rust/README.md new file mode 100644 index 0000000000..04dc48088a --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/README.md @@ -0,0 +1,156 @@ +## Eventmesh-rust-sdk + +Eventmesh rust sdk + +## Quickstart + +### Requirements + +1. rust toolchain, eventmesh's MSRV is 1.75. +2. protoc 3.15.0+ +3. setup eventmesh runtime + +### Add Dependency + +```toml +[dependencies] +eventmesh = { version = "1.9", features = ["default"] } +``` + +### Send message + +```rust +use std::time::{SystemTime, UNIX_EPOCH}; +use tracing::info; + +use eventmesh::config::EventMeshGrpcClientConfig; +use eventmesh::grpc::grpc_producer::EventMeshGrpcProducer; +use eventmesh::grpc::GrpcEventMeshMessageProducer; +use eventmesh::log; +use eventmesh::model::message::EventMeshMessage; + +#[eventmesh::main] +async fn main() -> Result<(), Box> { + log::init_logger(); + + let grpc_client_config = EventMeshGrpcClientConfig::new(); + let mut producer = GrpcEventMeshMessageProducer::new(grpc_client_config); + + //Publish Message + info!("Publish Message to EventMesh........"); + let message = EventMeshMessage::default() + .with_biz_seq_no("1") + .with_content("123") + .with_create_time(SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis() as u64) + .with_topic("123") + .with_unique_id("1111"); + let response = producer.publish(message.clone()).await?; + info!("Publish Message to EventMesh return result: {}", response); + + //Publish batch message + info!("Publish batch message to EventMesh........"); + let messages = vec![message.clone(), message.clone(), message.clone()]; + let response = producer.publish_batch(messages).await?; + info!( + "Publish batch message to EventMesh return result: {}", + response + ); + + //Publish batch message + info!("Publish request reply message to EventMesh........"); + let response = producer.request_reply(message.clone(), 1000).await?; + info!( + "Publish request reply message to EventMesh return result: {}", + response + ); + Ok(()) +} +``` + +### Subscribe message + +```rust +use std::time::Duration; + +use tracing::info; + +use eventmesh::common::ReceiveMessageListener; +use eventmesh::config::EventMeshGrpcClientConfig; +use eventmesh::grpc::grpc_consumer::EventMeshGrpcConsumer; +use eventmesh::log; +use eventmesh::model::message::EventMeshMessage; +use eventmesh::model::subscription::{SubscriptionItem, SubscriptionMode, SubscriptionType}; + +struct EventMeshListener; + +impl ReceiveMessageListener for EventMeshListener { + type Message = EventMeshMessage; + + fn handle(&self, msg: Self::Message) -> eventmesh::Result> { + info!("Receive message from eventmesh================{:?}", msg); + Ok(None) + } +} + +#[eventmesh::main] +async fn main() -> Result<(), Box> { + log::init_logger(); + let grpc_client_config = EventMeshGrpcClientConfig::new(); + let listener = Box::new(EventMeshListener); + let mut consumer = EventMeshGrpcConsumer::new(grpc_client_config, listener); + //send + let item = SubscriptionItem::new( + "TEST-TOPIC-GRPC-ASYNC", + SubscriptionMode::CLUSTERING, + SubscriptionType::ASYNC, + ); + info!("==========Start consumer======================\n{}", item); + let _response = consumer.subscribe(vec![item.clone()]).await?; + tokio::time::sleep(Duration::from_secs(1000)).await; + info!("=========Unsubscribe start================"); + let response = consumer.unsubscribe(vec![item.clone()]).await?; + println!("unsubscribe result:{}", response); + Ok(()) +} + +``` + +## Development Guide + +### Dependencies + +In order to build `tonic` >= 0.8.0, you need the `protoc` Protocol Buffers compiler, along with Protocol Buffers resource files. + +#### Ubuntu + +```bash +sudo apt update && sudo apt upgrade -y +sudo apt install -y protobuf-compiler libprotobuf-dev +``` + +#### Alpine Linux + +```sh +sudo apk add protoc protobuf-dev +``` + +#### macOS + +Assuming [Homebrew](https://brew.sh/) is already installed. (If not, see instructions for installing Homebrew on [the Homebrew website](https://brew.sh/).) + +```zsh +brew install protobuf +``` + +#### Windows + +- Download the latest version of `protoc-xx.y-win64.zip` from [HERE](https://github.com/protocolbuffers/protobuf/releases/latest) +- Extract the file `bin\protoc.exe` and put it somewhere in the `PATH` +- Verify installation by opening a command prompt and enter `protoc --version` + +### Build + +```shell +cargo build +``` + diff --git a/eventmesh-sdks/eventmesh-sdk-rust/build.rs b/eventmesh-sdks/eventmesh-sdk-rust/build.rs new file mode 100644 index 0000000000..55a010d4f7 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/build.rs @@ -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. + */ + +fn main() -> Result<(), Box> { + tonic_build::configure() + .build_client(true) + .build_server(false) + .compile( + &[ + "proto/eventmesh-service.proto", + "proto/eventmesh-cloudevents.proto", + ], + &["proto"], + )?; + Ok(()) +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/Cargo.toml b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/Cargo.toml deleted file mode 100644 index 9a13274af1..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/Cargo.toml +++ /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] -name = "eventmesh" -version = "0.1.0" -edition = "2021" -rust-version = "1.56" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.61" -prost = "0.11.0" -reqwest = { version = "0.11.11", features = ["json"] } -serde = { version = "1.0.143", features = ["derive"] } -serde_json = "1.0.83" -tonic = "0.8.0" -tokio = { version = "1.0", default-features = false, features = ["time"] } -futures-util = "0.3.23" -futures = "0.3.23" -tokio-stream = "0.1.9" - -[build-dependencies] -tonic-build = "0.8.0" diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/build.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/build.rs deleted file mode 100644 index be77dfa432..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/build.rs +++ /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. - -fn main() -> Result<(), Box> { - tonic_build::compile_protos("proto/eventmesh-client.proto")?; - Ok(()) -} \ No newline at end of file diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/proto/eventmesh-client.proto b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/proto/eventmesh-client.proto deleted file mode 100644 index ec831579b5..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/proto/eventmesh-client.proto +++ /dev/null @@ -1,150 +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. - -syntax = "proto3"; -package eventmesh.common.protocol.grpc; - -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-sdks/eventmesh-sdk-rust/eventmesh/src/constants.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/constants.rs deleted file mode 100644 index 835c9d68c8..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/constants.rs +++ /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. - -#[macro_export] macro_rules! const_str { - ($key: ident,$value:expr) => { - pub(crate) const $key: &str = $value; - }; -} -const_str!(EM_MESSAGE_PROTOCOL, "eventmeshmessage"); -const_str!(PROTOCOL_DESC, "http"); diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/config.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/config.rs deleted file mode 100644 index 63d59dca7f..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/config.rs +++ /dev/null @@ -1,54 +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. - -use crate::constants; - -use super::eventmesh_grpc::RequestHeader; - -#[derive(Debug, Clone)] -pub struct EventMeshGrpcConfig { - pub eventmesh_addr: String, - pub env: String, - pub idc: String, - pub ip: String, - pub pid: String, - pub sys: String, - pub user_name: String, - pub password: String, - pub producer_group: String, - pub consumer_group:String -} - -impl EventMeshGrpcConfig { - pub(crate) fn build_header(&self) -> RequestHeader { - RequestHeader { - env: self.env.to_string(), - region: String::from(""), - idc: self.idc.to_string(), - ip: self.ip.to_string(), - pid: self.pid.to_string(), - sys: self.sys.to_string(), - username: self.user_name.to_string(), - password: self.password.to_string(), - language: String::from("RUST"), - //TODO: cloudevent openmessage - protocol_type: String::from(constants::EM_MESSAGE_PROTOCOL), - protocol_version: String::from("1.0"), - protocol_desc: String::from("grpc"), - } - } -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/consumer.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/consumer.rs deleted file mode 100644 index 7bfdff3f52..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/consumer.rs +++ /dev/null @@ -1,263 +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. - -use std::{collections::HashMap, sync::Arc, time::Duration}; - -use futures::Stream; -use reqwest::header::HeaderValue; -use tokio::{ - sync::{ - mpsc::{self, Receiver, Sender}, - oneshot, Mutex, - }, - time::{interval, sleep}, -}; - -use tokio_stream::wrappers::ReceiverStream; -use tonic::{ - transport::{channel, Channel, Endpoint}, - IntoStreamingRequest, Request, Status, Streaming, -}; - -use crate::message::EventMeshMessage; - -use super::{ - config::EventMeshGrpcConfig, - eventmesh_grpc::{ - consumer_service_client::ConsumerServiceClient, - consumer_service_server::ConsumerServiceServer, - heartbeat::{ClientType, HeartbeatItem}, - heartbeat_service_client::HeartbeatServiceClient, - subscription::{subscription_item, Reply, SubscriptionItem}, - Heartbeat, RequestHeader, Response, SimpleMessage, Subscription, - }, - SDK_STREAM_URL, -}; -use anyhow::Result; -#[derive(Debug)] -struct HeartbeatInterval { - heartbeat_client: HeartbeatServiceClient, - subscription_map: Arc>>, - default_header: RequestHeader, - consumer_group: String, -} -impl HeartbeatInterval { - async fn send_heartbeat(&mut self) -> Result<()> { - let map = self.subscription_map.lock().await; - let resp = self - .heartbeat_client - .heartbeat(Heartbeat { - header: Some(self.default_header.clone()), - client_type: ClientType::Sub.into(), - // not set in java - producer_group: String::from(""), - consumer_group: self.consumer_group.to_string(), - heartbeat_items: map - .iter() - .map(|(key, value)| HeartbeatItem { - topic: key.to_string(), - url: value.to_string(), - }) - .collect(), - }) - .await?; - println!("heartbear: {:?}", resp.into_inner()); - Ok(()) - } - - async fn heartbeat(&mut self) -> Result<()> { - // EventMeshCommon.HEARTBEAT 30000 - let mut interval = interval(Duration::from_millis(30000)); - sleep(Duration::from_millis(10000)).await; - loop { - self.send_heartbeat().await?; - interval.tick().await; - } - } -} -#[derive(Debug)] -struct HeartbeatController { - receiver: oneshot::Receiver<()>, -} -impl HeartbeatController { - fn new( - map: Arc>>, - channel: Channel, - default_header: &RequestHeader, - consumer_group: &str, - ) -> Self { - let (mut sender, receiver) = oneshot::channel(); - let mut interval = HeartbeatInterval { - heartbeat_client: HeartbeatServiceClient::new(channel), - subscription_map: map, - default_header: default_header.clone(), - consumer_group: consumer_group.to_string(), - }; - tokio::spawn(async move { - tokio::select! { - _ = interval.heartbeat() => {}, - _ = sender.closed() => {} - } - }); - HeartbeatController { receiver } - } -} -#[derive(Debug)] -pub struct EventMeshMessageConsumer { - client: ConsumerServiceClient, - heartbeat: HeartbeatController, - default_header: RequestHeader, - // producer_group: String, - consumer_group: String, - producer_group:String, - subscription_map: Arc>>, - sender: Option>, -} - -impl EventMeshMessageConsumer { - pub async fn new(config: &EventMeshGrpcConfig) -> Result { - let channel = Endpoint::new(config.eventmesh_addr.clone())? - .connect() - .await?; - let client = ConsumerServiceClient::new(channel.clone()); - let header = config.build_header(); - let subscription_map = Arc::new(Mutex::new(HashMap::new())); - let heartbeat = HeartbeatController::new( - subscription_map.clone(), - channel, - &header, - &config.consumer_group, - ); - - Ok(EventMeshMessageConsumer { - client, - heartbeat, - default_header: header, - consumer_group: config.consumer_group.to_string(), - subscription_map, - sender: None, - producer_group: config.producer_group.to_string(), - }) - } - pub async fn unsubscribe_stream( - &mut self, - subscription_items: &Vec, - ) -> Result { - let resp = self.unsubscribe(subscription_items, SDK_STREAM_URL).await?; - Ok(resp) - } - pub async fn subscribe( - &mut self, - subscription_items: &Vec, - url: &str, - ) -> Result { - self.add_subscription(subscription_items, url).await; - let resp = self - .client - .subscribe(Subscription { - header: Some(self.default_header.clone()), - consumer_group: self.consumer_group.clone(), - subscription_items: subscription_items.clone(), - url: url.to_string(), - reply: None, - }) - .await?; - Ok(resp.into_inner()) - } - pub async fn unsubscribe( - &mut self, - subscription_items: &Vec, - url: &str, - ) -> Result { - self.remove_subscription(subscription_items).await; - let resp = self - .client - .unsubscribe(Subscription { - header: Some(self.default_header.clone()), - consumer_group: self.consumer_group.clone(), - subscription_items: subscription_items.clone(), - url: url.to_string(), - reply: None, - }) - .await?; - Ok(resp.into_inner()) - } - pub async fn stream_reply(&mut self, message: &EventMeshMessage) -> Result<()> { - let sender = self - .sender - .as_ref() - .ok_or(anyhow::anyhow!("sender not init"))?; - sender - .send(Subscription { - header: Some(self.default_header.clone()), - consumer_group: self.consumer_group.clone(), - subscription_items: vec![], - url: SDK_STREAM_URL.to_string(), - reply: Some(Reply { - producer_group: self.producer_group.clone(), - topic: message.topic.to_string(), - content: message.content.to_string(), - ttl: message.ttl.to_string(), - unique_id: message.unique_id.to_string(), - seq_num: message.biz_seq_no.to_string(), - tag: "".to_string(), - properties: HashMap::new(), - }), - }) - .await?; - Ok(()) - } - pub async fn subscribe_stream( - &mut self, - subscription_items: &Vec, - ) -> Result>> { - let sub = Subscription { - header: Some(self.default_header.clone()), - consumer_group: self.consumer_group.to_string(), - subscription_items: subscription_items.clone(), - url: String::from(SDK_STREAM_URL), - reply: None, - }; - self.add_subscription(subscription_items, SDK_STREAM_URL) - .await; - if self.sender.is_none() { - let (sender, receiver) = mpsc::channel::(16); - sender.send(sub).await?; - self.sender = Some(sender); - let resp = self - .client - .subscribe_stream(Request::new(ReceiverStream::new(receiver))) - .await?; - Ok(Some(resp.into_inner())) - } else { - self.sender.as_ref().unwrap().send(sub).await?; - Ok(None) - } - } - async fn add_subscription(&mut self, subscription_items: &Vec, url: &str) { - let mut map = self.subscription_map.lock().await; - subscription_items.iter().for_each(|item| { - map.insert(item.topic.to_string(), url.to_string()); - }); - } - async fn remove_subscription(&self, subscription_items: &Vec) { - let mut map = self.subscription_map.lock().await; - subscription_items.iter().for_each(|item| { - map.remove(&item.topic); - }); - } -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/mod.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/mod.rs deleted file mode 100644 index c7421ec595..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/mod.rs +++ /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. - -pub mod eventmesh_grpc { - tonic::include_proto!("eventmesh.common.protocol.grpc"); -} - -pub mod config; -pub mod producer; -pub mod consumer; -use crate::const_str; - -const_str!(SDK_STREAM_URL, "grpc_stream"); \ No newline at end of file diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/producer.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/producer.rs deleted file mode 100644 index d8a70661cc..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/grpc/producer.rs +++ /dev/null @@ -1,127 +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. - -use std::collections::HashMap; - -use crate::constants; -use crate::message::{EventMeshMessage, EventMeshMessageResp}; - -use super::config::EventMeshGrpcConfig; - -use super::eventmesh_grpc::batch_message::MessageItem; -use super::eventmesh_grpc::BatchMessage; -use super::eventmesh_grpc::{ - publisher_service_client::PublisherServiceClient, RequestHeader, SimpleMessage, -}; -use anyhow::{bail, Result}; -use tonic::transport::Channel; -pub struct EventMeshMessageProducer { - client: PublisherServiceClient, - producer_group: String, - default_header: RequestHeader, -} -impl EventMeshMessageProducer { - pub async fn new(config: &EventMeshGrpcConfig) -> Result { - let client = PublisherServiceClient::connect(config.eventmesh_addr.clone()).await?; - Ok(EventMeshMessageProducer { - client, - producer_group: config.producer_group.clone(), - default_header: config.build_header(), - }) - } - pub async fn batch_publish( - &mut self, - messages: &Vec, - ) -> Result { - if messages.is_empty() { - bail!("empty messages") - } - let resp = self - .client - .batch_publish(BatchMessage { - header: Some(self.default_header.clone()), - producer_group: self.producer_group.to_string(), - topic: messages[0].topic.to_string(), - message_item: messages - .iter() - .map( - |EventMeshMessage { - content, - ttl, - unique_id, - biz_seq_no, - topic: _, - }| MessageItem { - content: content.clone(), - ttl: ttl.to_string(), - unique_id: unique_id.clone(), - seq_num: biz_seq_no.clone(), - tag: String::from(""), - properties: HashMap::new(), - }, - ) - .collect(), - }) - .await? - .into_inner(); - Ok(EventMeshMessageResp { - ret_code: resp.resp_code.parse()?, - ret_msg: resp.resp_msg, - res_time: resp.resp_time.parse()?, - }) - } - pub async fn publish(&mut self, message: EventMeshMessage) -> Result { - let resp = self - .client - .publish(SimpleMessage { - header: Some(self.default_header.clone()), - producer_group: self.producer_group.to_string(), - topic: message.topic, - content: message.content, - ttl: message.ttl.to_string(), - unique_id: message.unique_id, - seq_num: message.biz_seq_no, - tag: "".to_string(), - properties: Default::default(), - }) - .await? - .into_inner(); - Ok(EventMeshMessageResp { - ret_code: resp.resp_code.parse()?, - ret_msg: resp.resp_msg, - res_time: resp.resp_time.parse()?, - }) - } - pub async fn request(&mut self, message: EventMeshMessage) -> Result { - let resp = self - .client - .request_reply(SimpleMessage { - header: Some(self.default_header.clone()), - producer_group: self.producer_group.to_string(), - topic: message.topic, - content: message.content, - ttl: message.ttl.to_string(), - unique_id: message.unique_id, - seq_num: message.biz_seq_no, - tag: "".to_string(), - properties: Default::default(), - }) - .await? - .into_inner(); - Ok(resp) - } -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/config.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/config.rs deleted file mode 100644 index 5576a69f65..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/config.rs +++ /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. - -#[derive(Debug, Clone)] -pub struct EventMeshHttpConfig { - pub eventmesh_addr: String, - pub env: String, - pub idc: String, - pub ip: String, - pub pid: String, - pub sys: String, - pub user_name: String, - pub password: String, - pub producergroup: String, -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/mod.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/mod.rs deleted file mode 100644 index 0f1947f155..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/mod.rs +++ /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. - -pub mod config; -pub mod producer; -mod protocol_key; -mod request_code; -mod protocol_version { - use std::fmt::Display; - - #[derive(Debug, Clone, Copy)] - pub(super) enum ProtocolVersion { - V1, - V2, - } - impl Display for ProtocolVersion { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ProtocolVersion::V1 => write!(f, "1.0"), - ProtocolVersion::V2 => write!(f, "2.0"), - } - } - } -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/producer.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/producer.rs deleted file mode 100644 index adc3c789e3..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/producer.rs +++ /dev/null @@ -1,117 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -use super::{config::EventMeshHttpConfig, protocol_key}; -use crate::{ - http::{protocol_version, request_code}, - message::{EventMeshMessage, EventMeshMessageResp}, constants, -}; -use anyhow::Result; -use reqwest::header::{self, HeaderValue}; -use serde::{Deserialize, Serialize}; - -pub struct EventMeshMessageProducer { - client: reqwest::Client, - producer_group: String, - url: String, -} -macro_rules! header { - ($header:expr,$key:expr, $value:expr) => { - $header.insert($key, HeaderValue::from_str(&$value)?); - }; -} -#[derive(Serialize)] -struct Body { - producergroup: String, - #[serde(flatten)] - body: EventMeshMessage, -} -impl EventMeshMessageProducer { - pub fn new(config: &EventMeshHttpConfig) -> Result { - let mut headers = header::HeaderMap::with_capacity(12); - - header!(headers, protocol_key::CLIENT_ENV, config.env); - header!(headers, protocol_key::CLIENT_IDC, config.idc); - header!(headers, protocol_key::CLIENT_IP, config.ip); - header!(headers, protocol_key::CLIENT_PID, config.pid); - header!(headers, protocol_key::CLIENT_SYS, config.sys); - header!(headers, protocol_key::CLIENT_USERNAME, config.user_name); - header!(headers, protocol_key::CLIENT_PASSWD, config.password); - header!( - headers, - protocol_key::VERSION, - protocol_version::ProtocolVersion::V1.to_string() - ); - header!( - headers, - protocol_key::PROTOCOL_TYPE, - constants::EM_MESSAGE_PROTOCOL - ); - header!( - headers, - protocol_key::RPOTOCOL_DESC, - constants::PROTOCOL_DESC - ); - // SpecVersion::V03 => "0.3", - // SpecVersion::V10 => "1.0", - header!(headers, protocol_key::PROTOCOL_VERSION, "1.0"); - header!(headers, protocol_key::LANGUAGE, "RUST"); - let client = reqwest::ClientBuilder::new().default_headers(headers); - Ok(EventMeshMessageProducer { - client: client.build()?, - producer_group: config.producergroup.clone(), - url: config.eventmesh_addr.clone(), - }) - } - - pub async fn publish(&self, message: EventMeshMessage) -> Result { - let body = Body { - producergroup: self.producer_group.clone(), - body: message, - }; - let resp = self - .client - .post(&self.url) - .header( - protocol_key::REQUEST_CODE, - request_code::RequestCode::MsgSendAsync.to_code(), - ) - .form(&body) - .send() - .await?; - let body: EventMeshMessageResp = resp.json().await?; - Ok(body) - } - pub async fn request(&self, message: EventMeshMessage) -> Result { - let body = Body { - producergroup: self.producer_group.clone(), - body: message, - }; - let resp = self - .client - .post(&self.url) - .header( - protocol_key::REQUEST_CODE, - request_code::RequestCode::MsgSendSync.to_code(), - ) - .form(&body) - .send() - .await?; - let body: EventMeshMessage = resp.json().await?; - Ok(body) - } -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/protocol_key.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/protocol_key.rs deleted file mode 100644 index 216c70cf6e..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/protocol_key.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. - -use crate::const_str; - -const_str!(REQUEST_CODE, "code"); -const_str!(VERSION, "version"); -const_str!(PROTOCOL_TYPE, "protocoltype"); -const_str!(RPOTOCOL_DESC, "protocoldesc"); -const_str!(PROTOCOL_VERSION, "protocolversion"); -const_str!(LANGUAGE, "language"); -// Protocol layer requester description -// ClientInstanceKey -const_str!(CLIENT_ENV, "env"); -const_str!(CLIENT_IDC, "idc"); -const_str!(CLIENT_IP, "ip"); -const_str!(CLIENT_PID, "pid"); -const_str!(CLIENT_SYS, "sys"); -const_str!(CLIENT_USERNAME, "username"); -const_str!(CLIENT_PASSWD, "passwd"); diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/request_code.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/request_code.rs deleted file mode 100644 index cb2ad6836d..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/http/request_code.rs +++ /dev/null @@ -1,76 +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. - -use std::fmt::Display; - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum RequestCode { - MsgBatchSend, - MsgBatchSendV2, - MsgSendSync, - MsgSendAsync, - HttpPushClientAsync, - HttpPushClientSync, - Register, - Unregister, - Heartbeat, - Subscribe, - ReplyMessage, - Unsubscribe, - AdminMetrics, - AdminShutdown, -} -impl Display for RequestCode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - RequestCode::MsgBatchSend => write!(f, "SEND BATCH MSG"), - RequestCode::MsgBatchSendV2 => write!(f, "SEND BATCH MSG V2"), - RequestCode::MsgSendSync => write!(f, "SEND SINGLE MSG SYNC"), - RequestCode::MsgSendAsync => write!(f, "SEND SINGLE MSG ASYNC"), - RequestCode::HttpPushClientAsync => write!(f, "PUSH CLIENT BY HTTP POST"), - RequestCode::HttpPushClientSync => write!(f, "PUSH CLIENT BY HTTP POST"), - RequestCode::Register => write!(f, "REGISTER"), - RequestCode::Unregister => write!(f, "UNREGISTER"), - RequestCode::Heartbeat => write!(f, "HEARTBEAT"), - RequestCode::Subscribe => write!(f, "SUBSCRIBE"), - RequestCode::ReplyMessage => write!(f, "REPLY MESSAGE"), - RequestCode::Unsubscribe => write!(f, "UNSUBSCRIBE"), - RequestCode::AdminMetrics => write!(f, "ADMIN METRICS"), - RequestCode::AdminShutdown => write!(f, "ADMIN SHUTDOWN"), - } - } -} -impl RequestCode { - pub(crate) fn to_code(&self) -> &'static str { - match self { - RequestCode::MsgBatchSend => "102", - RequestCode::MsgBatchSendV2 => "107", - RequestCode::MsgSendSync => "101", - RequestCode::MsgSendAsync => "104", - RequestCode::HttpPushClientAsync => "105", - RequestCode::HttpPushClientSync => "106", - RequestCode::Register => "201", - RequestCode::Unregister => "202", - RequestCode::Heartbeat => "203", - RequestCode::Subscribe => "206", - RequestCode::ReplyMessage => "301", - RequestCode::Unsubscribe => "207", - RequestCode::AdminMetrics => "603", - RequestCode::AdminShutdown => "601", - } - } -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/lib.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/lib.rs deleted file mode 100644 index b29efbfd49..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/lib.rs +++ /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. - -pub mod message; -pub mod http; -mod constants; -pub mod grpc; - diff --git a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/message.rs b/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/message.rs deleted file mode 100644 index 67114cd452..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/eventmesh/src/message.rs +++ /dev/null @@ -1,55 +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. - -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EventMeshMessage { - #[serde(rename = "bizseqno")] - pub biz_seq_no: String, - #[serde(rename = "uniqueid")] - pub unique_id: String, - pub topic: String, - pub content: String, - // pub prop: HashMap, - pub ttl: i32, - // pub(crate) create_time: u64, -} -impl EventMeshMessage { - pub fn new(biz_seq_no: &str, unique_id: &str, topic: &str, content: &str, ttl: i32) -> Self { - Self { - biz_seq_no: biz_seq_no.to_string(), - unique_id: unique_id.to_string(), - topic: topic.to_string(), - content: content.to_string(), - ttl, - // create_time: SystemTime::now() - // .duration_since(SystemTime::UNIX_EPOCH) - // .unwrap() - // .as_millis() - // .try_into() - // .unwrap(), - } - } -} -#[derive(Debug, Clone, Deserialize)] -#[serde(rename_all(deserialize = "camelCase"))] -pub struct EventMeshMessageResp { - pub ret_code: i32, - pub ret_msg: String, - pub res_time: u64, -} \ No newline at end of file diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/Cargo.lock b/eventmesh-sdks/eventmesh-sdk-rust/examples/Cargo.lock deleted file mode 100644 index c8aca65bc2..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/examples/Cargo.lock +++ /dev/null @@ -1,1044 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anyhow" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bumpalo" -version = "3.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" - -[[package]] -name = "bytes" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "encoding_rs" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "eventmesh" -version = "0.1.0" -dependencies = [ - "anyhow", - "reqwest", - "serde", - "serde_json", -] - -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "futures-channel" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-sink" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" - -[[package]] -name = "futures-task" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" - -[[package]] -name = "futures-util" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", -] - -[[package]] -name = "h2" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "http" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "http-producer" -version = "0.1.0" -dependencies = [ - "eventmesh", - "tokio", -] - -[[package]] -name = "httparse" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "hyper" -version = "0.14.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ipnet" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" - -[[package]] -name = "itoa" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" - -[[package]] -name = "js-sys" -version = "0.3.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.131" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40" - -[[package]] -name = "lock_api" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "mio" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys", -] - -[[package]] -name = "native-tls" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" - -[[package]] -name = "openssl" -version = "0.10.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "618febf65336490dfcf20b73f885f5651a0c89c64c2d4a8c3662585a70bf5bd0" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f9bd0c2710541a3cda73d6f9ac4f1b240de4ae261065d309dbe73d9dceb42f" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" - -[[package]] -name = "proc-macro2" -version = "1.0.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "reqwest" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "lazy_static", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "ryu" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" - -[[package]] -name = "schannel" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" -dependencies = [ - "lazy_static", - "windows-sys", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "security-framework" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.143" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.143" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "syn" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tempfile" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" -dependencies = [ - "autocfg", - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "once_cell", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-macros" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - -[[package]] -name = "unicode-bidi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" - -[[package]] -name = "unicode-ident" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" - -[[package]] -name = "unicode-normalization" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" - -[[package]] -name = "web-sys" -version = "0.3.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/Cargo.toml b/eventmesh-sdks/eventmesh-sdk-rust/examples/Cargo.toml deleted file mode 100644 index 80a81aa90e..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/examples/Cargo.toml +++ /dev/null @@ -1,63 +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] -name = "examples" -version = "0.0.0" -publish = false -edition = "2021" - -[dev-dependencies] -eventmesh = { path = "../eventmesh" } -tokio = { version = "1.0", features = ["full"] } -anyhow = "1.0" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -axum = "0.5.15" - -[[example]] -name = "http-producer-publish" -path = "http-producer-publish.rs" - -[[example]] -name = "http-producer-request" -path = "http-producer-request.rs" - - -[[example]] -name = "grpc-producer-publish" -path = "grpc-producer-publish.rs" - -[[example]] -name = "grpc-producer-batch-publish" -path = "grpc-producer-batch-publish.rs" - -[[example]] -name = "grpc-producer-request" -path = "grpc-producer-request.rs" - -[[example]] -name = "grpc-consumer" -path = "grpc-consumer.rs" - -[[example]] -name = "grpc-consumer-stream" -path = "grpc-consumer-stream.rs" - -[dependencies] -tracing = "0.1.36" -tracing-subscriber = "0.3.15" diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-consumer-stream.rs b/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-consumer-stream.rs deleted file mode 100644 index 0433f83b78..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-consumer-stream.rs +++ /dev/null @@ -1,93 +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. - -use std::fmt; - -use anyhow::Result; -use eventmesh::{ - grpc::{ - config::EventMeshGrpcConfig, - consumer::EventMeshMessageConsumer, - eventmesh_grpc::subscription::{ - subscription_item::{SubscriptionMode, SubscriptionType}, - SubscriptionItem, - }, - }, - message::EventMeshMessage, -}; -use serde::Serialize; -use tokio::{select, signal}; -use tracing::{info, Level}; -#[derive(Serialize)] -struct Content { - content: String, -} -#[tokio::main] -async fn main() -> Result<()> { - let collector = tracing_subscriber::fmt().init(); - info!("start!"); - let mut consumer = EventMeshMessageConsumer::new(&EventMeshGrpcConfig { - eventmesh_addr: "http://127.0.0.1:10205".to_string(), - env: "env".to_string(), - idc: "idc".to_string(), - ip: "127.0.0.1".to_string(), - pid: "1234".to_string(), - sys: "1234".to_string(), - user_name: "eventmesh".to_string(), - password: "pass".to_string(), - producer_group: "EventMeshTest-producerGroup".to_string(), - consumer_group: "EventMeshTest-consumerGroup".to_string(), - }) - .await?; - let item = vec![SubscriptionItem { - topic: String::from("TEST-TOPIC-GRPC-BROADCAST"), - mode: SubscriptionMode::Broadcasting.into(), - r#type: SubscriptionType::Sync.into(), - }]; - let mut stream = consumer.subscribe_stream(&item).await.unwrap().unwrap(); - let item2 = item.clone(); - - select! { - _ = signal::ctrl_c() => { - info!("shutting down"); - let resp = consumer.unsubscribe_stream(&item2).await; - info!("unsubscribe {:?}", resp); - }, - _ = async { - while let Ok(msg) = stream.message().await{ - match msg{ - Some(msg) => { - info!("receive: {:#?}", msg); - consumer.stream_reply(&EventMeshMessage::new( - "123456789012345678901234567893", - "123456789012345678901234567894", - "TEST-TOPIC-GRPC-BROADCAST", - &serde_json::to_string(&Content { - content: format!("testReplyMessage: {}",msg.content).to_string(), - }).unwrap(), - 5, - )).await.unwrap(); - }, - None => { info!("stream end"); break; }, - } - }; - let resp = consumer.unsubscribe_stream(&item2).await; - info!("unsubscribe {:?}", resp); - } => {} - } - Ok(()) -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-consumer.rs b/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-consumer.rs deleted file mode 100644 index be02f91c3b..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-consumer.rs +++ /dev/null @@ -1,81 +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. - -use std::{net::SocketAddr, sync::Arc}; - -use anyhow::Result; -use axum::{ - http::{HeaderMap, StatusCode}, - routing::post, - Router, -}; -use eventmesh::grpc::{ - config::EventMeshGrpcConfig, - consumer::EventMeshMessageConsumer, - eventmesh_grpc::subscription::{ - subscription_item::{SubscriptionMode, SubscriptionType}, - SubscriptionItem, - }, -}; -use tokio::{select, signal, sync::Mutex}; -async fn handler(headers: HeaderMap, body: String) -> StatusCode { - println!("{:#?} {:#?}", headers, body); - StatusCode::OK -} -#[tokio::main] -async fn main() -> Result<()> { - let app = Router::new().route("/", post(handler)); - let addr = SocketAddr::from(([127, 0, 0, 1], 8088)); - println!("listening on {}", addr); - let consumer = Arc::new(Mutex::new(EventMeshMessageConsumer::new(&EventMeshGrpcConfig { - eventmesh_addr: "http://127.0.0.1:10205".to_string(), - env: "env".to_string(), - idc: "idc".to_string(), - ip: "127.0.0.1".to_string(), - pid: "1234".to_string(), - sys: "1234".to_string(), - user_name: "eventmesh".to_string(), - password: "pass".to_string(), - producer_group: "EventMeshTest-producerGroup".to_string(), - consumer_group: "EventMeshTest-consumerGroup".to_string(), - }) - .await?)); - let item = vec![SubscriptionItem { - topic: String::from("TEST-TOPIC-GRPC-BROADCAST"), - mode: SubscriptionMode::Broadcasting.into(), - r#type: SubscriptionType::Sync.into(), - }]; - let consumer2 = consumer.clone(); - let item2 = item.clone(); - let url = "http://host.docker.internal:8088/"; - let server = tokio::spawn(async move { - select! { - _ = axum::Server::bind(&addr).serve(app.into_make_service()) => {}, - _ = signal::ctrl_c() => { - println!("shutting down"); - let mut consumer = consumer2.lock().await; - let resp = consumer.unsubscribe(&item2, url).await; - println!("unsubscribe {:?}", resp); - } - }; - }); - - let resp = consumer.lock().await.subscribe(&item, url).await?; - println!("subscribe {:?}", resp); - server.await?; - Ok(()) -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-producer-batch-publish.rs b/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-producer-batch-publish.rs deleted file mode 100644 index c6a358bc20..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-producer-batch-publish.rs +++ /dev/null @@ -1,57 +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. - -use anyhow::Result; -use eventmesh::{ - grpc::{config::EventMeshGrpcConfig, producer::EventMeshMessageProducer}, - message::EventMeshMessage, -}; -use serde::Serialize; - -#[derive(Serialize)] -struct Content { - content: String, -} - -#[tokio::main] -async fn main() -> Result<()> { - let mut producer = EventMeshMessageProducer::new(&EventMeshGrpcConfig { - eventmesh_addr: "http://127.0.0.1:10205".to_string(), - env: "env".to_string(), - idc: "idc".to_string(), - ip: "127.0.0.1".to_string(), - pid: "1234".to_string(), - sys: "1234".to_string(), - user_name: "eventmesh".to_string(), - password: "pass".to_string(), - producer_group: "EventMeshTest-producerGroup".to_string(), - consumer_group: "EventMeshTest-consumerGroup".to_string() - }).await?; - let resp = producer - .batch_publish(&vec![EventMeshMessage::new( - "123456789012345678901234567891", - "123456789012345678901234567892", - "TEST-TOPIC-GRPC-BROADCAST", - &serde_json::to_string(&Content { - content: "testPublishMessage".to_string(), - })?, - 5, - )]) - .await?; - println!("{:#?}", resp); - Ok(()) -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-producer-publish.rs b/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-producer-publish.rs deleted file mode 100644 index e663fbd953..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-producer-publish.rs +++ /dev/null @@ -1,57 +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. - -use anyhow::Result; -use eventmesh::{ - grpc::{config::EventMeshGrpcConfig, producer::EventMeshMessageProducer}, - message::EventMeshMessage, -}; -use serde::Serialize; - -#[derive(Serialize)] -struct Content { - content: String, -} - -#[tokio::main] -async fn main() -> Result<()> { - let mut producer = EventMeshMessageProducer::new(&EventMeshGrpcConfig { - eventmesh_addr: "http://127.0.0.1:10205".to_string(), - env: "env".to_string(), - idc: "idc".to_string(), - ip: "127.0.0.1".to_string(), - pid: "1234".to_string(), - sys: "1234".to_string(), - user_name: "eventmesh".to_string(), - password: "pass".to_string(), - producer_group: "EventMeshTest-producerGroup".to_string(), - consumer_group: "EventMeshTest-consumerGroup".to_string() - }).await?; - let resp = producer - .publish(EventMeshMessage::new( - "123456789012345678901234567891", - "123456789012345678901234567892", - "TEST-TOPIC-GRPC-BROADCAST", - &serde_json::to_string(&Content { - content: "testPublishMessage".to_string(), - })?, - 5, - )) - .await?; - println!("{:#?}", resp); - Ok(()) -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-producer-request.rs b/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-producer-request.rs deleted file mode 100644 index af72f910f7..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc-producer-request.rs +++ /dev/null @@ -1,57 +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. - -use anyhow::Result; -use eventmesh::{ - grpc::{config::EventMeshGrpcConfig, producer::EventMeshMessageProducer}, - message::EventMeshMessage, -}; -use serde::Serialize; - -#[derive(Serialize)] -struct Content { - content: String, -} - -#[tokio::main] -async fn main() -> Result<()> { - let mut producer = EventMeshMessageProducer::new(&EventMeshGrpcConfig { - eventmesh_addr: "http://127.0.0.1:10205".to_string(), - env: "env".to_string(), - idc: "idc".to_string(), - ip: "127.0.0.1".to_string(), - pid: "1234".to_string(), - sys: "1234".to_string(), - user_name: "eventmesh".to_string(), - password: "pass".to_string(), - producer_group: "EventMeshTest-producerGroup".to_string(), - consumer_group: "EventMeshTest-consumerGroup".to_string() - }).await?; - let resp = producer - .request(EventMeshMessage::new( - "123456789012345678901234567891", - "123456789012345678901234567892", - "TEST-TOPIC-GRPC-RR", - &serde_json::to_string(&Content { - content: "testRequestMessage".to_string(), - })?, - 5, - )) - .await?; - println!("{:#?}", resp); - Ok(()) -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc/consumer_example.rs b/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc/consumer_example.rs new file mode 100644 index 0000000000..8f84875d69 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc/consumer_example.rs @@ -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. + */ +use std::time::Duration; + +use tracing::info; + +use eventmesh::common::ReceiveMessageListener; +use eventmesh::config::EventMeshGrpcClientConfig; +use eventmesh::grpc::grpc_consumer::EventMeshGrpcConsumer; +use eventmesh::log; +use eventmesh::model::message::EventMeshMessage; +use eventmesh::model::subscription::{SubscriptionItem, SubscriptionMode, SubscriptionType}; + +struct EventMeshListener; + +impl ReceiveMessageListener for EventMeshListener { + type Message = EventMeshMessage; + + fn handle(&self, msg: Self::Message) -> eventmesh::Result> { + info!("Receive message from eventmesh================{:?}", msg); + Ok(None) + } +} + +#[eventmesh::main] +async fn main() -> Result<(), Box> { + log::init_logger(); + let grpc_client_config = EventMeshGrpcClientConfig::new(); + let listener = Box::new(EventMeshListener); + let mut consumer = EventMeshGrpcConsumer::new(grpc_client_config, listener); + //send + let item = SubscriptionItem::new( + "TEST-TOPIC-GRPC-ASYNC", + SubscriptionMode::CLUSTERING, + SubscriptionType::ASYNC, + ); + info!("==========Start consumer======================\n{}", item); + let _response = consumer.subscribe(vec![item.clone()]).await?; + tokio::time::sleep(Duration::from_secs(1000)).await; + info!("=========Unsubscribe start================"); + let response = consumer.unsubscribe(vec![item.clone()]).await?; + println!("unsubscribe result:{}", response); + Ok(()) +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc/producer_example.rs b/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc/producer_example.rs new file mode 100644 index 0000000000..959c1a6a02 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/examples/grpc/producer_example.rs @@ -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. + */ +use std::time::{SystemTime, UNIX_EPOCH}; + +use chrono::Utc; +use cloudevents::{EventBuilder, EventBuilderV10}; +use tracing::info; + +use eventmesh::common::ProtocolKey; +use eventmesh::config::EventMeshGrpcClientConfig; +use eventmesh::grpc::grpc_producer::EventMeshGrpcProducer; +use eventmesh::grpc::GrpcEventMeshProducer; +use eventmesh::log; +use eventmesh::model::message::EventMeshMessage; + +#[eventmesh::main] +async fn main() -> Result<(), Box> { + log::init_logger(); + + //Publish Message + #[cfg(feature = "eventmesh_message")] + { + let grpc_client_config = EventMeshGrpcClientConfig::new(); + let mut producer = GrpcEventMeshProducer::new(grpc_client_config); + info!("Publish Message to EventMesh........"); + let message = EventMeshMessage::default() + .with_biz_seq_no("1") + .with_content("123") + .with_create_time(SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis() as u64) + .with_topic("123") + .with_unique_id("1111"); + let response = producer.publish(message.clone()).await?; + info!("Publish Message to EventMesh return result: {}", response); + + //Publish batch message + info!("Publish batch message to EventMesh........"); + let messages = vec![message.clone(), message.clone(), message.clone()]; + let response = producer.publish_batch(messages).await?; + info!( + "Publish batch message to EventMesh return result: {}", + response + ); + + //Publish batch message + info!("Publish request reply message to EventMesh........"); + let response = producer.request_reply(message.clone(), 1000).await?; + info!( + "Publish request reply message to EventMesh return result: {}", + response + ); + } + + #[cfg(feature = "cloud_events")] + { + let grpc_client_config = EventMeshGrpcClientConfig::new(); + let mut producer = GrpcEventMeshProducer::new(grpc_client_config); + info!("Publish Message to EventMesh........"); + let message = EventBuilderV10::new() + .id("my_event.my_application") + .source("http://localhost:8080") + .subject("mxsm") + .ty("example.demo") + .time(Utc::now()) + .data(ProtocolKey::CLOUDEVENT_CONTENT_TYPE, "{\"aaa\":\"1111\"}") + .build()?; + let response = producer.publish(message.clone()).await?; + info!("Publish Message to EventMesh return result: {}", response); + + //Publish batch message + info!("Publish batch message to EventMesh........"); + let messages = vec![message.clone(), message.clone(), message.clone()]; + let response = producer.publish_batch(messages).await?; + info!( + "Publish batch message to EventMesh return result: {}", + response + ); + + //Publish batch message + info!("Publish request reply message to EventMesh........"); + let response = producer.request_reply(message.clone(), 1000).await?; + info!( + "Publish request reply message to EventMesh return result: {}", + response + ); + } + + Ok(()) +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/http-producer-publish.rs b/eventmesh-sdks/eventmesh-sdk-rust/examples/http-producer-publish.rs deleted file mode 100644 index 960826e410..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/examples/http-producer-publish.rs +++ /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. - -use anyhow::Result; -use eventmesh::{ - http::{config::EventMeshHttpConfig, producer::EventMeshMessageProducer}, - message::EventMeshMessage, -}; -use serde::Serialize; - -#[derive(Serialize)] -struct Content { - content: String, -} - -#[tokio::main] -async fn main() -> Result<()> { - let producer = EventMeshMessageProducer::new(&EventMeshHttpConfig { - eventmesh_addr: "http://127.0.0.1:10105".to_string(), - env: "env".to_string(), - idc: "idc".to_string(), - ip: "127.0.0.1".to_string(), - pid: "1234".to_string(), - sys: "1234".to_string(), - user_name: "eventmesh".to_string(), - password: "pass".to_string(), - producergroup: "EventMeshTest-producerGroup".to_string(), - })?; - let resp = producer - .publish(EventMeshMessage::new( - "123456789012345678901234567891", - "123456789012345678901234567892", - "TEST-TOPIC-HTTP-ASYNC", - &serde_json::to_string(&Content { - content: "testPublishMessage".to_string(), - })?, - 5, - )) - .await?; - println!("{:#?}", resp); - Ok(()) -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/examples/http-producer-request.rs b/eventmesh-sdks/eventmesh-sdk-rust/examples/http-producer-request.rs deleted file mode 100644 index c3de248b01..0000000000 --- a/eventmesh-sdks/eventmesh-sdk-rust/examples/http-producer-request.rs +++ /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. - -use anyhow::Result; -use eventmesh::{ - http::{config::EventMeshHttpConfig, producer::EventMeshMessageProducer}, - message::EventMeshMessage, -}; -use serde::Serialize; - -#[derive(Serialize)] -struct Content { - content: String, -} - -#[tokio::main] -async fn main() -> Result<()> { - let producer = EventMeshMessageProducer::new(&EventMeshHttpConfig { - eventmesh_addr: "http://127.0.0.1:10105".to_string(), - env: "env".to_string(), - idc: "idc".to_string(), - ip: "127.0.0.1".to_string(), - pid: "1234".to_string(), - sys: "1234".to_string(), - user_name: "".to_string(), - password: "".to_string(), - producergroup: "EventMeshTest-producerGroup".to_string(), - })?; - let resp = producer - .request(EventMeshMessage::new( - "123456789012345678901234567891", - "123456789012345678901234567892", - "TEST-TOPIC-GRPC-RR", - &serde_json::to_string(&Content { - content: "testPublishMessage".to_string(), - })?, - 5, - )) - .await?; - println!("{:#?}", resp); - Ok(()) -} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/proto/eventmesh-cloudevents.proto b/eventmesh-sdks/eventmesh-sdk-rust/proto/eventmesh-cloudevents.proto new file mode 100644 index 0000000000..37e07a0b40 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/proto/eventmesh-cloudevents.proto @@ -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. + */ + + + +/** + * CloudEvent Protobuf Format + * + * - Required context attributes are explicitly represented. + * - Optional and Extension context attributes are carried in a map structure. + * - Data may be represented as binary, text, or protobuf messages. + */ + +syntax = "proto3"; + +package org.apache.eventmesh.cloudevents.v1; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; + +option java_package = "org.apache.eventmesh.common.protocol.grpc.cloudevents"; +option java_multiple_files = true; +option java_outer_classname = "EventMeshCloudEvents"; + + +message CloudEvent { + + // -- CloudEvent Context Attributes + + // Required Attributes + string id = 1; + string source = 2; // URI-reference + string spec_version = 3; + string type = 4; + + // Optional & Extension Attributes + map attributes = 5; + + // -- CloudEvent Data (Bytes, Text, or Proto) + oneof data { + bytes binary_data = 6; + string text_data = 7; + google.protobuf.Any proto_data = 8; + } + + /** + * The CloudEvent specification defines + * seven attribute value types... + */ + + message CloudEventAttributeValue { + + oneof attr { + bool ce_boolean = 1; + int32 ce_integer = 2; + string ce_string = 3; + bytes ce_bytes = 4; + string ce_uri = 5; + string ce_uri_ref = 6; + google.protobuf.Timestamp ce_timestamp = 7; + } + } +} + +/** + * CloudEvent Protobuf Batch Format + * + */ + +message CloudEventBatch { + repeated CloudEvent events = 1; +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/proto/eventmesh-service.proto b/eventmesh-sdks/eventmesh-sdk-rust/proto/eventmesh-service.proto new file mode 100644 index 0000000000..99d57bc514 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/proto/eventmesh-service.proto @@ -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. + */ +syntax = "proto3"; + +package org.apache.eventmesh.cloudevents.v1; + +import "google/protobuf/empty.proto"; +import "eventmesh-cloudevents.proto"; + +option java_package = "org.apache.eventmesh.common.protocol.grpc.cloudevents"; +option java_multiple_files = true; +option java_outer_classname = "EventMeshGrpcService"; + + +service PublisherService { + //publish event + rpc publish(CloudEvent) returns (CloudEvent); + + //publish event with reply + rpc requestReply(CloudEvent) returns (CloudEvent); + + //publish event one way + rpc publishOneWay(CloudEvent) returns (google.protobuf.Empty); + + // publish batch event + rpc batchPublish(CloudEventBatch) returns (CloudEvent); + + //publish batch event one way + rpc batchPublishOneWay(CloudEventBatch) returns (google.protobuf.Empty); +} + +service ConsumerService { + // The subscribed event will be delivered by invoking the webhook url in the Subscription + rpc subscribe(CloudEvent) returns (CloudEvent); + + // The subscribed event will be delivered through stream of Message + rpc subscribeStream(stream CloudEvent) returns (stream CloudEvent); + + rpc unsubscribe(CloudEvent) returns (CloudEvent); +} + +service HeartbeatService { + rpc heartbeat(CloudEvent) returns (CloudEvent); +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/common.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/common.rs new file mode 100644 index 0000000000..7b3ea0d018 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/common.rs @@ -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. + */ +//! Common utilities for eventmesh. + +/// Constants. +pub mod constants; + +/// Eventmesh message utilities. +pub mod grpc_eventmesh_message_utils; + +/// Local IP helper. +pub(crate) mod local_ip; + +/// Protocol keys. +mod protocol_key; + +/// Random string generator. +mod random_string_util; + +/// Re-export protocol keys. +pub use crate::common::protocol_key::ProtocolKey; + +/// Re-export random string generator. +pub use crate::common::random_string_util::RandomStringUtils; + +/// Trait for message listener. +pub trait ReceiveMessageListener: Sync + Send { + /// Message type. + type Message; + + /// Handle received message. + /// + /// # Arguments + /// + /// * `msg` - The received message. + /// + /// # Returns + /// + /// The processed message or error. + fn handle(&self, msg: Self::Message) -> crate::Result>; +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/common/constants.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/common/constants.rs new file mode 100644 index 0000000000..5c0ef06907 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/common/constants.rs @@ -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. + */ +pub const DEFAULT_EVENTMESH_MESSAGE_TTL: i32 = 4000; +pub const SDK_STREAM_URL: &str = "grpc_stream"; + +pub struct DataContentType; + +impl DataContentType { + pub const TEXT_PLAIN: &'static str = "text/plain"; + pub const JSON: &'static str = "application/json"; +} + +pub(crate) struct SpecVersion; + +#[allow(dead_code)] +impl SpecVersion { + pub(crate) const V1: &'static str = "1.0"; + pub(crate) const V03: &'static str = "0.3"; +} + +#[derive(Debug, PartialEq, Eq)] +pub enum ClientType { + PUB, + SUB, +} + +impl ClientType { + pub fn get(type_: i32) -> Option { + match type_ { + 1 => Some(ClientType::PUB), + 2 => Some(ClientType::SUB), + _ => None, + } + } + + pub fn contains(client_type: i32) -> bool { + match client_type { + 1 | 2 => true, + _ => false, + } + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/common/grpc_eventmesh_message_utils.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/common/grpc_eventmesh_message_utils.rs new file mode 100644 index 0000000000..c1ff9a3221 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/common/grpc_eventmesh_message_utils.rs @@ -0,0 +1,671 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use std::any::Any; +use std::collections::{HashMap, HashSet}; +use std::fmt::Debug; +use std::time::{SystemTime, UNIX_EPOCH}; + +use cloudevents::Data::String as EventString; +use cloudevents::{AttributesReader, Data, Event, EventBuilder, EventBuilderV10}; +use tonic::transport::Uri; + +use crate::common::constants::{DataContentType, SpecVersion, DEFAULT_EVENTMESH_MESSAGE_TTL}; +use crate::common::{ProtocolKey, RandomStringUtils}; +use crate::config::EventMeshGrpcClientConfig; +use crate::model::message::EventMeshMessage; +use crate::model::response::EventMeshResponse; +use crate::model::subscription::SubscriptionItem; +use crate::model::EventMeshProtocolType; +use crate::proto_cloud_event::{PbAttr, PbCloudEvent, PbCloudEventAttributeValue, PbData}; + +pub struct ProtoSupport; + +impl ProtoSupport { + pub fn is_text_content(content_type: &str) -> bool { + if content_type.is_empty() { + return false; + } + + content_type.starts_with("text/") + || content_type == "application/json" + || content_type == "application/xml" + || content_type.ends_with("+json") + || content_type.ends_with("+xml") + } + + pub fn is_proto_content(content_type: &str) -> bool { + content_type == "application/protobuf" + } +} + +pub struct EventMeshCloudEventUtils; + +impl EventMeshCloudEventUtils { + const CLOUD_EVENT_TYPE: &'static str = "org.apache.eventmesh"; + + pub fn build_common_cloud_event_attributes( + client_config: &EventMeshGrpcClientConfig, + protocol_type: EventMeshProtocolType, + ) -> HashMap { + let mut attribute_value_map = HashMap::with_capacity(64); + attribute_value_map.insert( + ProtocolKey::ENV.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(client_config.env.clone())), + }, + ); + attribute_value_map.insert( + ProtocolKey::IDC.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(client_config.idc.clone())), + }, + ); + attribute_value_map.insert( + ProtocolKey::IP.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(crate::common::local_ip::get_local_ip_v4())), + }, + ); + attribute_value_map.insert( + ProtocolKey::PID.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(std::process::id().to_string())), + }, + ); + attribute_value_map.insert( + ProtocolKey::SYS.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(client_config.sys.clone())), + }, + ); + attribute_value_map.insert( + ProtocolKey::LANGUAGE.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(client_config.language.clone())), + }, + ); + attribute_value_map.insert( + ProtocolKey::USERNAME.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(client_config.user_name.clone())), + }, + ); + attribute_value_map.insert( + ProtocolKey::PASSWD.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(client_config.password.clone())), + }, + ); + attribute_value_map.insert( + ProtocolKey::PROTOCOL_TYPE.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString( + protocol_type.protocol_type_name().to_string(), + )), + }, + ); + attribute_value_map.insert( + ProtocolKey::PROTOCOL_VERSION.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(SpecVersion::V1.to_string())), + }, + ); + attribute_value_map + } + + pub fn build_event_subscription( + client_config: &EventMeshGrpcClientConfig, + protocol_type: EventMeshProtocolType, + url: &str, + subscription_items: &[SubscriptionItem], + ) -> Option { + if subscription_items.is_empty() { + return None; + } + let subscription_item_set: HashSet = + subscription_items.iter().cloned().collect(); + let mut attribute_value_map = + Self::build_common_cloud_event_attributes(client_config, protocol_type); + attribute_value_map.insert( + ProtocolKey::CONSUMERGROUP.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(client_config.consumer_group.clone()?)), + }, + ); + attribute_value_map.insert( + ProtocolKey::DATA_CONTENT_TYPE.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(DataContentType::JSON.to_string())), + }, + ); + if !url.trim().is_empty() { + attribute_value_map.insert( + ProtocolKey::URL.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(url.to_string())), + }, + ); + } + let subscription_item_json = serde_json::to_string(&subscription_item_set); + if subscription_item_json.is_err() { + return None; + } + Some(PbCloudEvent { + id: RandomStringUtils::generate_uuid(), + source: Uri::builder() + .path_and_query("/") + .build() + .unwrap() + .to_string(), + spec_version: SpecVersion::V1.to_string(), + r#type: Self::CLOUD_EVENT_TYPE.to_string(), + attributes: attribute_value_map, + data: Some(PbData::TextData(subscription_item_json.unwrap())), + }) + } + + pub fn build_event_mesh_cloud_event( + message: T, + client_config: &EventMeshGrpcClientConfig, + ) -> Option + where + T: Any, + { + let message_any = &message as &dyn Any; + + if let Some(em_message) = message_any.downcast_ref::() { + return Some(Self::switch_event_mesh_message_2_event_mesh_cloud_event( + em_message, + client_config, + EventMeshProtocolType::EventMeshMessage, + )); + } + if let Some(cloud_event) = message_any.downcast_ref::() { + return Some(Self::switch_cloud_event_2_event_mesh_cloud_event( + cloud_event, + client_config, + EventMeshProtocolType::CloudEvents, + )); + } + + None + } + + pub fn switch_event_mesh_message_2_event_mesh_cloud_event( + message: &EventMeshMessage, + client_config: &EventMeshGrpcClientConfig, + protocol_type: EventMeshProtocolType, + ) -> PbCloudEvent { + let mut attribute_value_map = + Self::build_common_cloud_event_attributes(client_config, protocol_type); + let ttl = message + .get_prop(ProtocolKey::TTL) + .cloned() + .unwrap_or_else(|| DEFAULT_EVENTMESH_MESSAGE_TTL.to_string()); + let seq_num = message + .biz_seq_no + .clone() + .unwrap_or_else(|| RandomStringUtils::generate_num(30)); + let unique_id = message + .unique_id + .clone() + .unwrap_or_else(|| RandomStringUtils::generate_num(30)); + attribute_value_map + .entry(ProtocolKey::DATA_CONTENT_TYPE.to_string()) + .or_insert_with(|| PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(DataContentType::TEXT_PLAIN.to_string())), + }); + + attribute_value_map.insert( + ProtocolKey::TTL.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(ttl.to_string())), + }, + ); + attribute_value_map.insert( + ProtocolKey::SEQ_NUM.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(seq_num.to_string())), + }, + ); + + attribute_value_map.insert( + ProtocolKey::SEQ_NUM.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(seq_num.to_string())), + }, + ); + + attribute_value_map.insert( + ProtocolKey::PROTOCOL_DESC.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString( + ProtocolKey::PROTOCOL_DESC_GRPC_CLOUD_EVENT.to_string(), + )), + }, + ); + + attribute_value_map.insert( + ProtocolKey::UNIQUE_ID.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(unique_id.to_string())), + }, + ); + attribute_value_map.insert( + ProtocolKey::PRODUCERGROUP.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString( + client_config.producer_group.clone().unwrap(), + )), + }, + ); + if let Some(topic) = &message.topic { + attribute_value_map.insert( + ProtocolKey::SUBJECT.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(topic.to_string())), + }, + ); + } + attribute_value_map.insert( + ProtocolKey::DATA_CONTENT_TYPE.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(DataContentType::TEXT_PLAIN.to_string())), + }, + ); + let props = &message.prop; + let text_plain = DataContentType::TEXT_PLAIN.to_string(); + let data_content_type = props + .get(ProtocolKey::DATA_CONTENT_TYPE) + .unwrap_or(&text_plain); + props.iter().for_each(|(key, value)| { + attribute_value_map.insert( + key.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(value.to_string())), + }, + ); + }); + + let data = { + if let Some(content) = &message.content { + if ProtoSupport::is_text_content(data_content_type) { + Some(PbData::TextData(content.to_string())) + } else if ProtoSupport::is_proto_content(data_content_type) { + Some(PbData::ProtoData(prost_types::Any { + type_url: String::from(""), + value: content.clone().into_bytes(), + })) + } else { + Some(PbData::BinaryData(content.clone().into_bytes())) + } + } else { + None + } + }; + PbCloudEvent { + id: RandomStringUtils::generate_uuid(), + source: Uri::builder() + .path_and_query("/") + .build() + .unwrap() + .to_string(), + spec_version: SpecVersion::V1.to_string(), + r#type: Self::CLOUD_EVENT_TYPE.to_string(), + attributes: attribute_value_map, + data, + } + } + + pub fn switch_cloud_event_2_event_mesh_cloud_event( + message: &Event, + client_config: &EventMeshGrpcClientConfig, + protocol_type: EventMeshProtocolType, + ) -> PbCloudEvent { + let mut attribute_value_map = + Self::build_common_cloud_event_attributes(client_config, protocol_type); + let ttl = message + .extension(ProtocolKey::TTL) + .map_or(DEFAULT_EVENTMESH_MESSAGE_TTL.to_string(), |value| { + value.to_string() + }); + let seq_num = message + .extension(ProtocolKey::SEQ_NUM) + .map_or(RandomStringUtils::generate_num(30), |value| { + value.to_string() + }); + let unique_id = message.id().to_string(); + attribute_value_map + .entry(ProtocolKey::DATA_CONTENT_TYPE.to_string()) + .or_insert_with(|| PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(DataContentType::TEXT_PLAIN.to_string())), + }); + + attribute_value_map.insert( + ProtocolKey::TTL.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(ttl.to_string())), + }, + ); + attribute_value_map.insert( + ProtocolKey::SEQ_NUM.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(seq_num.to_string())), + }, + ); + + attribute_value_map.insert( + ProtocolKey::SEQ_NUM.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(seq_num.to_string())), + }, + ); + + attribute_value_map.insert( + ProtocolKey::PROTOCOL_DESC.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString( + ProtocolKey::PROTOCOL_DESC_GRPC_CLOUD_EVENT.to_string(), + )), + }, + ); + + attribute_value_map.insert( + ProtocolKey::UNIQUE_ID.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(unique_id.to_string())), + }, + ); + attribute_value_map.insert( + ProtocolKey::PRODUCERGROUP.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString( + client_config.producer_group.clone().unwrap(), + )), + }, + ); + + attribute_value_map.insert( + ProtocolKey::SUBJECT.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(message.subject().unwrap().to_string())), + }, + ); + + attribute_value_map.insert( + ProtocolKey::DATA_CONTENT_TYPE.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(DataContentType::TEXT_PLAIN.to_string())), + }, + ); + message.iter_extensions().for_each(|(key, value)| { + attribute_value_map.insert( + key.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(value.to_string())), + }, + ); + }); + + let data = { + if let Some(content) = message.data() { + match content { + Data::Binary(bytes) => Some(PbData::ProtoData(prost_types::Any { + type_url: String::from(""), + value: bytes.clone(), + })), + EventString(string) => Some(PbData::TextData(string.clone())), + Data::Json(_json) => None, + } + } else { + None + } + }; + PbCloudEvent { + id: RandomStringUtils::generate_uuid(), + source: Uri::builder() + .path_and_query("/") + .build() + .unwrap() + .to_string(), + spec_version: SpecVersion::V1.to_string(), + r#type: Self::CLOUD_EVENT_TYPE.to_string(), + attributes: attribute_value_map, + data, + } + } + + pub fn build_message_from_event_mesh_cloud_event(cloud_event: &PbCloudEvent) -> Option + where + T: Any + Debug + From, + { + let seq = EventMeshCloudEventUtils::get_seq_num(cloud_event); + let unique_id = EventMeshCloudEventUtils::get_unique_id(cloud_event); + + if seq.is_empty() || unique_id.is_empty() { + return None; + } + Some(T::from(cloud_event.clone())) + } + + pub(crate) fn switch_event_mesh_cloud_event_2_event_mesh_message( + cloud_event: &PbCloudEvent, + ) -> EventMeshMessage { + let mut prop = HashMap::new(); + cloud_event.attributes.iter().for_each(|(key, value)| { + prop.insert( + key.to_string(), + (&(value.attr)).clone().unwrap().to_string(), + ); + }); + let topic = EventMeshCloudEventUtils::get_subject(cloud_event); + let biz_seq_no = EventMeshCloudEventUtils::get_seq_num(cloud_event); + let unique_id = EventMeshCloudEventUtils::get_unique_id(cloud_event); + let content = EventMeshCloudEventUtils::get_text_data(cloud_event); + EventMeshMessage { + biz_seq_no: Some(biz_seq_no), + unique_id: Some(unique_id), + topic: Some(topic), + content: Some(content), + prop, + create_time: SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_or_else(|_err| 0u64, |time| time.as_millis() as u64), + } + } + + pub(crate) fn switch_event_mesh_cloud_event_2_cloud_event(cloud_event: PbCloudEvent) -> Event { + let topic = EventMeshCloudEventUtils::get_subject(&cloud_event); + let unique_id = EventMeshCloudEventUtils::get_unique_id(&cloud_event); + let content = EventMeshCloudEventUtils::get_text_data(&cloud_event); + let source = EventMeshCloudEventUtils::get_source(&cloud_event); + + let mut builder = EventBuilderV10::new() + .id(unique_id) + .subject(topic) + .source(source) + .ty(ProtocolKey::CLOUD_EVENTS_PROTOCOL_NAME) + .data(DataContentType::JSON, content); + + for (key, value) in cloud_event.attributes { + builder = builder.extension(key.as_str(), value.attr.clone().unwrap().to_string()); + } + + builder.build().unwrap() + } + + #[allow(dead_code)] + pub(crate) fn switch_cloud_event_2_event_mesh_message(cloud_event: Event) -> EventMeshMessage { + let mut prop = HashMap::new(); + cloud_event.iter_attributes().for_each(|(key, value)| { + prop.insert(key.to_string(), value.to_string()); + }); + let topic = cloud_event.subject().unwrap().to_string(); + let biz_seq_no = cloud_event + .extension(ProtocolKey::SEQ_NUM) + .unwrap() + .to_string(); + let unique_id = cloud_event.id().to_string(); + let content = cloud_event.data().unwrap().to_string(); + EventMeshMessage { + biz_seq_no: Some(biz_seq_no), + unique_id: Some(unique_id), + topic: Some(topic), + content: Some(content), + prop, + create_time: SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_or_else(|_err| 0u64, |time| time.as_millis() as u64), + } + } + + pub fn get_seq_num(cloud_event: &PbCloudEvent) -> String { + cloud_event + .attributes + .get(ProtocolKey::SEQ_NUM) + .map_or_else( + || String::new(), + |ce| { + ce.attr + .clone() + .unwrap_or(PbAttr::CeString(String::new())) + .to_string() + }, + ) + } + + pub fn get_unique_id(cloud_event: &PbCloudEvent) -> String { + cloud_event + .attributes + .get(ProtocolKey::UNIQUE_ID) + .map_or_else( + || String::new(), + |ce| { + ce.attr + .clone() + .unwrap_or(PbAttr::CeString(String::new())) + .to_string() + }, + ) + } + + pub fn get_data_content(cloud_event: &PbCloudEvent) -> String { + cloud_event + .attributes + .get(ProtocolKey::DATA_CONTENT_TYPE) + .map_or_else( + || String::new(), + |ce| { + ce.attr + .clone() + .unwrap_or(PbAttr::CeString(String::new())) + .to_string() + }, + ) + } + + pub fn get_subject(cloud_event: &PbCloudEvent) -> String { + cloud_event + .attributes + .get(ProtocolKey::SUBJECT) + .map_or_else( + || String::new(), + |ce| { + ce.attr + .clone() + .unwrap_or(PbAttr::CeString(String::new())) + .to_string() + }, + ) + } + + pub fn get_text_data(cloud_event: &PbCloudEvent) -> String { + cloud_event + .data + .clone() + .unwrap_or(PbData::TextData(String::new())) + .to_string() + } + + pub fn get_source(cloud_event: &PbCloudEvent) -> String { + cloud_event.attributes.get(ProtocolKey::SOURCE).map_or_else( + || String::new(), + |ce| { + ce.attr + .clone() + .unwrap_or(PbAttr::CeString(String::new())) + .to_string() + }, + ) + } + + pub fn get_response(cloud_event: &PbCloudEvent) -> EventMeshResponse { + let code = cloud_event + .attributes + .get(ProtocolKey::GRPC_RESPONSE_CODE) + .map_or_else( + || None, + |val| { + if let Some(ref value) = val.attr { + Some(value.to_string()) + } else { + None + } + }, + ); + let msg = cloud_event + .attributes + .get(ProtocolKey::GRPC_RESPONSE_MESSAGE) + .map_or_else( + || None, + |val| { + if let Some(ref value) = val.attr { + Some(value.to_string()) + } else { + None + } + }, + ); + let time = cloud_event + .attributes + .get(ProtocolKey::GRPC_RESPONSE_TIME) + .map_or_else( + || None, + |val| { + if let Some(ref value) = val.attr { + Some(value.to_string().parse::().unwrap_or(0)) + } else { + None + } + }, + ); + EventMeshResponse::new(code, msg, time) + } + + pub fn get_ttl(cloud_event: &PbCloudEvent) -> String { + cloud_event.attributes.get(ProtocolKey::TTL).map_or_else( + || String::new(), + |ce| { + ce.attr + .clone() + .unwrap_or(PbAttr::CeString(String::new())) + .to_string() + }, + ) + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/common/local_ip.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/common/local_ip.rs new file mode 100644 index 0000000000..4c46a2931d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/common/local_ip.rs @@ -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. + */ +use local_ip_address::local_ip; +use std::net::{IpAddr, Ipv4Addr}; + +/// Get local IPv4 address. +/// +/// Get local IPv4 address, fallback to 127.0.0.1 if failed. +/// +/// # Returns +/// +/// The local IPv4 address as string. +pub(crate) fn get_local_ip_v4() -> String { + let ip_addr = local_ip().unwrap_or(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))); + ip_addr.to_string() +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/common/protocol_key.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/common/protocol_key.rs new file mode 100644 index 0000000000..c4f4b27778 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/common/protocol_key.rs @@ -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. + */ +pub struct ProtocolKey; + +#[allow(dead_code)] +impl ProtocolKey { + // EventMesh extensions + pub const ENV: &'static str = "env"; + pub const IDC: &'static str = "idc"; + pub const SYS: &'static str = "sys"; + pub const PID: &'static str = "pid"; + pub const IP: &'static str = "ip"; + pub const USERNAME: &'static str = "username"; + pub const PASSWD: &'static str = "passwd"; + pub const LANGUAGE: &'static str = "language"; + pub const PROTOCOL_TYPE: &'static str = "protocoltype"; + pub const PROTOCOL_VERSION: &'static str = "protocolversion"; + pub const PROTOCOL_DESC: &'static str = "protocoldesc"; + pub const SEQ_NUM: &'static str = "seqnum"; + pub const UNIQUE_ID: &'static str = "uniqueid"; + pub const TTL: &'static str = "ttl"; + pub const PRODUCERGROUP: &'static str = "producergroup"; + pub const CONSUMERGROUP: &'static str = "consumergroup"; + pub const TAG: &'static str = "tag"; + pub const CONTENT_TYPE: &'static str = "contenttype"; + pub const PROPERTY_MESSAGE_CLUSTER: &'static str = "cluster"; + pub const URL: &'static str = "url"; + pub const CLIENT_TYPE: &'static str = "clienttype"; + pub const GRPC_RESPONSE_CODE: &'static str = "status_code"; + pub const GRPC_RESPONSE_MESSAGE: &'static str = "response_message"; + pub const GRPC_RESPONSE_TIME: &'static str = "time"; + + pub const SUB_MESSAGE_TYPE: &'static str = "submessagetype"; + + // CloudEvents spec + pub const ID: &'static str = "id"; + pub const SOURCE: &'static str = "source"; + pub const SPECVERSION: &'static str = "specversion"; + pub const TYPE: &'static str = "type"; + pub const DATA_CONTENT_TYPE: &'static str = "datacontenttype"; + pub const DATA_SCHEMA: &'static str = "dataschema"; + pub const SUBJECT: &'static str = "subject"; + pub const TIME: &'static str = "time"; + pub const EVENT_DATA: &'static str = "eventdata"; + + //protocol desc + pub const PROTOCOL_DESC_GRPC_CLOUD_EVENT: &'static str = "grpc-cloud-event"; + + pub const CLOUD_EVENTS_PROTOCOL_NAME: &'static str = "cloudevents"; + + pub const CLOUDEVENT_CONTENT_TYPE: &'static str = "application/cloudevents+json"; +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/common/random_string_util.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/common/random_string_util.rs new file mode 100644 index 0000000000..71c48a7248 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/common/random_string_util.rs @@ -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. + */ +use rand::distributions::Alphanumeric; +use rand::Rng; +use std::iter; +use uuid; + +pub struct RandomStringUtils; + +impl RandomStringUtils { + /// Generate a random alphanumeric string. + /// + /// Generate a random string with given length, containing alphanumeric characters. + /// + /// # Arguments + /// + /// * `length` - The length of generated string. + /// + /// # Returns + /// + /// The randomly generated string. + pub fn generate_num(length: usize) -> String { + let random_string = iter::repeat(()) + .map(|()| rand::thread_rng().sample(Alphanumeric) as char) + .take(length) + .collect(); + random_string + } + + /// Generate a random UUID string. + /// + /// # Returns + /// + /// The randomly generated UUID string. + pub fn generate_uuid() -> String { + let uuid = uuid::Uuid::new_v4(); + uuid.to_string() + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/config.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/config.rs new file mode 100644 index 0000000000..3deb30beb7 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/config.rs @@ -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. + */ + +//! Configurations. + +/// gRPC client configuration. +mod grpc_config; + +#[cfg(feature = "grpc")] + +/// Re-export gRPC client configuration when "grpc" feature is enabled. +pub use crate::config::grpc_config::EventMeshGrpcClientConfig; diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/config/grpc_config.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/config/grpc_config.rs new file mode 100644 index 0000000000..25855a0d7f --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/config/grpc_config.rs @@ -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. + */ +#[derive(Debug, Clone)] +pub struct EventMeshGrpcClientConfig { + pub(crate) server_addr: String, + pub(crate) server_port: u32, + pub(crate) env: String, + pub(crate) consumer_group: Option, + pub(crate) producer_group: Option, + pub(crate) idc: String, + pub(crate) sys: String, + pub(crate) user_name: String, + pub(crate) password: String, + pub(crate) language: String, + pub(crate) use_tls: Option, + pub(crate) time_out: Option, +} + +impl Default for EventMeshGrpcClientConfig { + fn default() -> Self { + Self { + server_addr: "localhost".to_string(), + server_port: 10205, + env: "dev".to_string(), + consumer_group: Some("DefaultConsumerGroup".to_string()), + producer_group: Some("DefaultProducerGroup".to_string()), + idc: "default".to_string(), + sys: "evetmesh".to_string(), + user_name: "username".to_string(), + password: "password".to_string(), + language: "Rust".to_string(), + use_tls: Some(false), + time_out: Some(5000), + } + } +} + +impl ToString for EventMeshGrpcClientConfig { + fn to_string(&self) -> String { + format!( + "ClientConfig={{ServerAddr={},ServerPort={},env={:?},\ + idc={:?},producerGroup={:?},consumerGroup={:?},\ + sys={:?},userName={:?},password=***,\ + useTls={:?},timeOut={:?}}}", + self.server_addr, + self.server_port, + self.env, + self.idc, + self.producer_group, + self.consumer_group, + self.sys, + self.user_name, + self.use_tls, + self.time_out + ) + } +} + +#[allow(dead_code)] +impl EventMeshGrpcClientConfig { + pub fn new() -> Self { + Default::default() + } + + pub fn set_server_addr(mut self, server_addr: String) -> Self { + self.server_addr = server_addr; + self + } + pub fn set_server_port(mut self, server_port: u32) -> Self { + self.server_port = server_port; + self + } + pub fn set_env(mut self, env: String) -> Self { + self.env = env; + self + } + pub fn set_consumer_group(mut self, consumer_group: String) -> Self { + self.consumer_group = Some(consumer_group); + self + } + pub fn set_producer_group(mut self, producer_group: String) -> Self { + self.producer_group = Some(producer_group); + self + } + pub fn set_idc(mut self, idc: String) -> Self { + self.idc = idc; + self + } + pub fn set_sys(mut self, sys: String) -> Self { + self.sys = sys; + self + } + pub fn set_user_name(mut self, user_name: String) -> Self { + self.user_name = user_name; + self + } + pub fn set_password(mut self, password: String) -> Self { + self.password = password; + self + } + pub fn set_language(mut self, language: String) -> Self { + self.language = language; + self + } + pub fn set_use_tls(mut self, use_tls: bool) -> Self { + self.use_tls = Some(use_tls); + self + } + pub fn set_time_out(mut self, time_out: u64) -> Self { + self.time_out = Some(time_out); + self + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/error.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/error.rs new file mode 100644 index 0000000000..3315a0ae4f --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/error.rs @@ -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. + */ + +use std::fmt::{Display, Formatter}; +use thiserror::Error; + +#[allow(dead_code)] +#[derive(Debug, Error)] +pub enum EventMeshError { + /// Invalid arguments + InvalidArgs(String), + + /// gRpc status + #[cfg(feature = "grpc")] + GRpcStatus(#[from] tonic::Status), + + EventMeshLocal(String), + + EventMeshRemote(String), + + EventMeshFromStrError(String), +} + +impl Display for EventMeshError { + #[inline] + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + #[cfg(feature = "grpc")] + EventMeshError::GRpcStatus(e) => write!(f, "grpc request error: {}", e), + EventMeshError::EventMeshLocal(ref err_msg) => { + write!(f, "EventMesh client error: {}", err_msg) + } + EventMeshError::EventMeshRemote(ref err_msg) => { + write!(f, "EventMesh remote error: {}", err_msg) + } + EventMeshError::EventMeshFromStrError(ref err_msg) => { + write!(f, "EventMesh Parse from String error: {}", err_msg) + } + EventMeshError::InvalidArgs(ref err_msg) => { + write!(f, "Invalid args: {}", err_msg) + } + } + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/grpc.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc.rs new file mode 100644 index 0000000000..30046f8c5a --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc.rs @@ -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. + */ + +//! gRPC client implementations. + +/// EventMesh message types. +pub(crate) mod r#impl; + +/// gRPC consumer client. +pub mod grpc_consumer; + +/// gRPC producer client. +pub mod grpc_producer; + +/// Protobuf generated definitions. +pub(crate) mod pb; + +#[cfg(feature = "grpc")] +/// Re-export gRPC eventmesh message producer when features enabled. +pub use crate::grpc::r#impl::grpc_producer_impl::GrpcEventMeshProducer; diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/grpc_consumer.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/grpc_consumer.rs new file mode 100644 index 0000000000..e31c97a530 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/grpc_consumer.rs @@ -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. + */ +use std::collections::HashMap; +use std::sync::Arc; +use std::time::Duration; + +use futures::lock::Mutex; +use tonic::codegen::tokio_stream::StreamExt; +use tracing::error; + +use crate::common::constants::{DataContentType, SDK_STREAM_URL}; +use crate::common::grpc_eventmesh_message_utils::EventMeshCloudEventUtils; +use crate::common::{ProtocolKey, ReceiveMessageListener}; +use crate::config::EventMeshGrpcClientConfig; +use crate::error::EventMeshError::{EventMeshLocal, InvalidArgs}; +use crate::model::message::EventMeshMessage; +use crate::model::response::EventMeshResponse; +use crate::model::subscription::{ + HeartbeatItem, SubscriptionItem, SubscriptionItemWrapper, SubscriptionReply, +}; +use crate::model::EventMeshProtocolType; +use crate::net::GrpcClient; +use crate::proto_cloud_event::{PbAttr, PbCloudEvent, PbCloudEventAttributeValue, PbData}; + +pub struct EventMeshGrpcConsumer { + inner: GrpcClient, + grpc_config: EventMeshGrpcClientConfig, + subscription_map: Arc>>, + listener: Arc>>, +} + +impl EventMeshGrpcConsumer { + pub fn new( + grpc_config: EventMeshGrpcClientConfig, + listener: Box>, + ) -> Self { + let client = GrpcClient::new(&grpc_config).unwrap(); + let subscription_map = Arc::new(Mutex::new(HashMap::with_capacity(16))); + let listener = Arc::new(listener); + let _ = EventMeshGrpcConsumer::heartbeat( + client.clone(), + grpc_config.clone(), + Arc::clone(&subscription_map), + ); + Self { + inner: client, + grpc_config, + subscription_map: Arc::clone(&subscription_map), + listener: Arc::clone(&listener), + } + } + + pub async fn subscribe_webhook( + &mut self, + subscription_items: Vec, + url: impl Into, + ) -> crate::Result { + if subscription_items.is_empty() { + return Err(InvalidArgs("subscription_items is empty".to_string()).into()); + } + let cloud_event = EventMeshCloudEventUtils::build_event_subscription( + &self.grpc_config, + EventMeshProtocolType::EventMeshMessage, + url.into().as_str(), + &subscription_items, + ); + if cloud_event.is_none() { + return Err( + EventMeshLocal("SubscriptionItem switch to CloudEvent error".to_string()).into(), + ); + } + let result = self + .inner + .subscribe_webhook_inner(cloud_event.unwrap()) + .await?; + Ok(EventMeshCloudEventUtils::get_response(&result)) + } + + pub async fn subscribe( + &mut self, + subscription_items: Vec, + ) -> crate::Result<()> { + if subscription_items.is_empty() { + return Err(InvalidArgs("subscription_items is empty".to_string()).into()); + } + + let map = self.subscription_map.clone(); + let mut guard = map.lock().await; + subscription_items.iter().for_each(|item| { + guard.insert( + item.topic.clone(), + SubscriptionItemWrapper { + subscription_item: item.clone(), + url: SDK_STREAM_URL.to_string(), + }, + ); + }); + let cloud_event = EventMeshCloudEventUtils::build_event_subscription( + &self.grpc_config, + EventMeshProtocolType::EventMeshMessage, + String::new().as_str(), + &subscription_items, + ); + if cloud_event.is_none() { + return Err( + EventMeshLocal("SubscriptionItem switch to CloudEvent error".to_string()).into(), + ); + } + let (keeper, mut resp_stream) = self.inner.subscribe_bi_inner(cloud_event.unwrap()).await?; + let listener_inner = Arc::clone(&self.listener); + tokio::spawn(async move { + while let Some(received) = resp_stream.next().await { + if let Err(status) = received { + error!("Subscribe receive error, status {}", status); + continue; + } + let mut received = received.unwrap(); + let eventmesh_message = + EventMeshCloudEventUtils::build_message_from_event_mesh_cloud_event::< + EventMeshMessage, + >(&received); + if eventmesh_message.is_none() { + continue; + } + received.attributes.insert( + ProtocolKey::DATA_CONTENT_TYPE.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(DataContentType::JSON.to_string())), + }, + ); + + let handled_msg = listener_inner.handle(eventmesh_message.unwrap()); + if let Ok(msg_option) = handled_msg { + if let Some(_msg) = msg_option { + received.attributes.insert( + ProtocolKey::SUB_MESSAGE_TYPE.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString( + SubscriptionReply::SUB_TYPE.to_string(), + )), + }, + ); + received.data = None; + let _ = keeper.sender.send(received).await; + } + } else { + error!("Handle Receive error:{}", handled_msg.unwrap_err()) + } + } + }); + Ok(()) + } + + pub async fn unsubscribe( + &mut self, + unsubscription_items: Vec, + ) -> crate::Result { + if unsubscription_items.is_empty() { + return Err(InvalidArgs("unsubscription_items is empty".to_string()).into()); + } + let map = self.subscription_map.clone(); + let mut guard = map.lock().await; + unsubscription_items.iter().for_each(|item| { + guard.remove(item.topic.as_str()); + }); + let cloud_event = EventMeshCloudEventUtils::build_event_subscription( + &self.grpc_config, + EventMeshProtocolType::EventMeshMessage, + String::new().as_str(), + &unsubscription_items, + ); + if cloud_event.is_none() { + return Err( + EventMeshLocal("SubscriptionItem switch to CloudEvent error".to_string()).into(), + ); + } + let result = self.inner.unsubscribe_inner(cloud_event.unwrap()).await?; + Ok(EventMeshCloudEventUtils::get_response(&result)) + } + + fn heartbeat( + mut client: GrpcClient, + grpc_config: EventMeshGrpcClientConfig, + subscription_map: Arc>>, + ) -> crate::Result<()> { + tokio::spawn(async move { + loop { + tokio::time::sleep(Duration::from_secs(20)).await; + let mut attributes = EventMeshCloudEventUtils::build_common_cloud_event_attributes( + &grpc_config, + EventMeshProtocolType::EventMeshMessage, + ); + attributes.insert( + ProtocolKey::CONSUMERGROUP.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString( + grpc_config.consumer_group.clone().unwrap(), + )), + }, + ); + attributes.insert( + ProtocolKey::CLIENT_TYPE.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeInteger(2)), + }, + ); + attributes.insert( + ProtocolKey::DATA_CONTENT_TYPE.to_string(), + PbCloudEventAttributeValue { + attr: Some(PbAttr::CeString(DataContentType::JSON.to_string())), + }, + ); + + let map = subscription_map.lock().await; + let heartbeat_items = map + .iter() + .filter_map(|(key, value)| { + Some(HeartbeatItem { + topic: key.to_string(), + url: value.url.clone(), + }) + }) + .collect::>(); + let mut cloud_event = PbCloudEvent::default(); + cloud_event.attributes = attributes; + cloud_event.data = Some(PbData::TextData( + serde_json::to_string(&heartbeat_items).unwrap(), + )); + let _result = client.heartbeat_inner(cloud_event).await; + } + }); + Ok(()) + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/grpc_producer.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/grpc_producer.rs new file mode 100644 index 0000000000..867588fb88 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/grpc_producer.rs @@ -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. + */ +//! Trait for gRPC eventmesh producer. + +use crate::model::response::EventMeshResponse; +use std::future::Future; + +/// Trait for gRPC eventmesh producer. +pub trait EventMeshGrpcProducer { + /// Publish a message. + fn publish(&mut self, message: M) -> impl Future>; + + /// Publish a batch of messages. + fn publish_batch( + &mut self, + messages: Vec, + ) -> impl Future>; + + /// Request reply for a message. + fn request_reply( + &mut self, + message: M, + time_out: u64, + ) -> impl Future>; +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/impl.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/impl.rs new file mode 100644 index 0000000000..edb47941c5 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/impl.rs @@ -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. + */ + +#[cfg(feature = "grpc")] +pub mod grpc_producer_impl; diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/impl/grpc_producer_impl.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/impl/grpc_producer_impl.rs new file mode 100644 index 0000000000..f81c3f65e7 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/impl/grpc_producer_impl.rs @@ -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. + */ +use std::any::Any; +use std::fmt::Debug; +use std::marker::PhantomData; + +use tonic::transport::Uri; + +use crate::common::constants::{DataContentType, DEFAULT_EVENTMESH_MESSAGE_TTL}; +use crate::common::grpc_eventmesh_message_utils::EventMeshCloudEventUtils; +use crate::config::EventMeshGrpcClientConfig; +use crate::error::EventMeshError; +use crate::grpc::grpc_producer::EventMeshGrpcProducer; +use crate::model::message::EventMeshMessage; +use crate::model::response::EventMeshResponse; +use crate::model::EventMeshProtocolType; +use crate::net::GrpcClient; +use crate::proto_cloud_event::{ + EventMeshCloudEventBuilder, PbCloudEvent, PbCloudEventBatch, PbData, +}; + +/// gRPC EventMesh message producer. +pub struct GrpcEventMeshProducer { + /// gRPC client. + inner: GrpcClient, + + /// gRPC configuration. + grpc_config: EventMeshGrpcClientConfig, + + _mark: PhantomData, +} + +impl GrpcEventMeshProducer +where + M: Any, +{ + pub fn new(grpc_config: EventMeshGrpcClientConfig) -> Self { + let client = GrpcClient::new(&grpc_config).unwrap(); + Self { + inner: client, + grpc_config, + _mark: PhantomData::, + } + } + + #[allow(dead_code)] + fn build_event_mesh_cloud_event(&mut self, message: EventMeshMessage) -> PbCloudEvent { + let mut event = EventMeshCloudEventBuilder::default() + .with_env(self.grpc_config.env.clone()) + .with_idc(self.grpc_config.idc.clone()) + .with_ip(crate::common::local_ip::get_local_ip_v4()) + .with_pid(std::process::id().to_string()) + .with_sys(self.grpc_config.sys.clone()) + .with_user_name(self.grpc_config.user_name.clone()) + .with_password(self.grpc_config.password.clone()) + .with_language("Rust") + .with_protocol_type(EventMeshProtocolType::CloudEvents.protocol_type_name()) + .with_ttl(DEFAULT_EVENTMESH_MESSAGE_TTL.to_string()) + .with_subject(message.biz_seq_no.clone().unwrap()) + .with_producergroup( + self.grpc_config + .producer_group + .clone() + .map_or_else(|| String::from("Default_Producer_Group"), |val| val) + .clone(), + ) + .with_uniqueid(message.unique_id.unwrap()) + .with_data_content_type(DataContentType::TEXT_PLAIN) + .build(); + event.id = message.biz_seq_no.clone().unwrap(); + event.source = Uri::builder() + .path_and_query("/") + .build() + .unwrap() + .to_string(); + event.spec_version = "1.0".to_string(); + event.r#type = "Rust".to_string(); + event.data = Some(PbData::TextData(message.content.unwrap().into())); + event + } + + fn build_event_mesh_cloud_event_batch( + &mut self, + messages: Vec, + ) -> Option { + if messages.is_empty() { + return None; + } + + let events = messages + .into_iter() + .map(|msg| { + EventMeshCloudEventUtils::build_event_mesh_cloud_event(msg, &self.grpc_config) + .unwrap() + }) + .collect(); + + let mut cloud_event_batch = PbCloudEventBatch::default(); + cloud_event_batch.events = events; + + Some(cloud_event_batch) + } +} + +/// gRPC EventMesh message producer implementation. +#[allow(unused_variables)] +impl EventMeshGrpcProducer for GrpcEventMeshProducer +where + M: Any + Debug + From, +{ + /// Publish a message. + async fn publish(&mut self, message: M) -> crate::Result { + let event = + EventMeshCloudEventUtils::build_event_mesh_cloud_event(message, &self.grpc_config); + if event.is_none() { + return Err(EventMeshError::EventMeshLocal( + "Create Event Mesh cloud event Error".to_string(), + ) + .into()); + } + let result = self.inner.publish_inner(event.unwrap()).await?; + Ok(EventMeshCloudEventUtils::get_response(&result)) + } + + /// Publish a batch of messages. + async fn publish_batch(&mut self, messages: Vec) -> crate::Result { + let events = self.build_event_mesh_cloud_event_batch(messages); + if events.is_none() { + return Err(EventMeshError::EventMeshLocal("Vec is empty".to_string()).into()); + } + let result = self.inner.batch_publish_inner(events.unwrap()).await?; + Ok(EventMeshCloudEventUtils::get_response(&result)) + } + + /// Request reply for a message. + async fn request_reply(&mut self, message: M, time_out: u64) -> crate::Result { + let event = + EventMeshCloudEventUtils::build_event_mesh_cloud_event(message, &self.grpc_config); + let result = self + .inner + .request_reply_inner(event.unwrap(), time_out) + .await?; + Ok(EventMeshCloudEventUtils::build_message_from_event_mesh_cloud_event(&result).unwrap()) + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/pb.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/pb.rs new file mode 100644 index 0000000000..26e69e91a9 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/grpc/pb.rs @@ -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. + */ +pub mod cloud_events { + tonic::include_proto!("org.apache.eventmesh.cloudevents.v1"); +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/lib.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/lib.rs new file mode 100644 index 0000000000..a03f8cfa2d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/lib.rs @@ -0,0 +1,323 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +//! +//! + +/// Re-export eventmesh main. +pub use eventmesh::main; +/// Re-export eventmesh as tokio. +pub use tokio as eventmesh; + +/// Shorthand for `anyhow::Result`. +pub type Result = anyhow::Result; + +// Modules + +/// Configurations. +pub mod config; + +/// Errors. +pub(crate) mod error; + +/// Network utils. +mod net; + +/// Common utilities. +pub mod common; + +/// gRPC client implementations. +pub mod grpc; + +/// Logging. +pub mod log; + +/// Data models. +pub mod model; + +/// Module contains Protobuf CloudEvent related types and builder. +pub mod proto_cloud_event { + use cloudevents::Event; + + use crate::common::ProtocolKey; + /// Protobuf CloudEvent attribute value enum. + pub use crate::grpc::pb::cloud_events::cloud_event::cloud_event_attribute_value::Attr as PbAttr; + use crate::grpc::pb::cloud_events::cloud_event::cloud_event_attribute_value::Attr; + pub use crate::grpc::pb::cloud_events::cloud_event::CloudEventAttributeValue as PbCloudEventAttributeValue; + pub use crate::grpc::pb::cloud_events::cloud_event::Data as PbData; + use crate::grpc::pb::cloud_events::cloud_event::{CloudEventAttributeValue, Data}; + /// Protobuf CloudEvent message. + pub use crate::grpc::pb::cloud_events::{ + CloudEvent as PbCloudEvent, CloudEventBatch as PbCloudEventBatch, + }; + use crate::model::message::EventMeshMessage; + + impl ToString for PbAttr { + /// Convert Protobuf attribute to String. + fn to_string(&self) -> String { + match self { + Attr::CeBoolean(value) => value.to_string(), + Attr::CeInteger(value) => value.to_string(), + Attr::CeString(value) => value.clone(), + Attr::CeBytes(value) => unsafe { String::from_utf8_unchecked(value.clone()) }, + Attr::CeUri(value) => value.clone(), + Attr::CeUriRef(value) => value.clone(), + Attr::CeTimestamp(value) => value.to_string(), + } + } + } + + impl From for PbCloudEvent { + fn from(_value: EventMeshMessage) -> Self { + todo!() + } + } + + impl From for PbCloudEvent { + fn from(_value: Event) -> Self { + todo!() + } + } + + impl ToString for PbData { + /// Convert Protobuf data to String. + fn to_string(&self) -> String { + match self { + Data::BinaryData(value) => unsafe { String::from_utf8_unchecked(value.clone()) }, + Data::TextData(value) => value.clone(), + Data::ProtoData(value) => unsafe { + String::from_utf8_unchecked(value.value.clone()) + }, + } + } + } + + /// Builder for constructing Protobuf CloudEvent. + #[derive(Debug, Default)] + pub struct EventMeshCloudEventBuilder { + /// Environment attribute. + pub(crate) env: String, + + /// IDC attribute. + pub(crate) idc: String, + + /// IP address attribute. + pub(crate) ip: String, + + /// Optional process ID attribute. + pub(crate) pid: Option, + + /// System attribute. + pub(crate) sys: String, + + /// Username attribute. + pub(crate) user_name: String, + + /// Password attribute. + pub(crate) password: String, + + /// Language attribute. + pub(crate) language: String, + + /// Protocol type attribute. + pub(crate) protocol_type: String, + + /// Protocol version attribute. + pub(crate) protocol_version: String, + + /// TTL attribute. + pub(crate) ttl: String, + + /// Subject attribute. + pub(crate) subject: String, + + /// Producer group attribute. + pub(crate) producergroup: String, + + /// Unique ID attribute. + pub(crate) uniqueid: String, + + /// Data content type attribute. + pub(crate) data_content_type: String, + } + + impl EventMeshCloudEventBuilder { + /// Set process ID attribute. + pub fn with_pid(mut self, pid: impl Into) -> Self { + self.pid = Some(pid.into()); + self + } + + /// Set environment attribute. + pub fn with_env(mut self, env: impl Into) -> Self { + self.env = env.into(); + self + } + + /// Set IDC attribute. + pub fn with_idc(mut self, idc: impl Into) -> Self { + self.idc = idc.into(); + self + } + + /// Set IP address attribute. + pub fn with_ip(mut self, ip: impl Into) -> Self { + self.ip = ip.into(); + self + } + + /// Set system attribute. + pub fn with_sys(mut self, sys: impl Into) -> Self { + self.sys = sys.into(); + self + } + + /// Set username attribute. + pub fn with_user_name(mut self, user_name: impl Into) -> Self { + self.user_name = user_name.into(); + self + } + + /// Set password attribute. + pub fn with_password(mut self, password: impl Into) -> Self { + self.password = password.into(); + self + } + + /// Set language attribute. + pub fn with_language(mut self, language: impl Into) -> Self { + self.language = language.into(); + self + } + + /// Set protocol type attribute. + pub fn with_protocol_type(mut self, protocol_type: impl Into) -> Self { + self.protocol_type = protocol_type.into(); + self + } + + /// Set protocol version attribute. + pub fn with_protocol_version(mut self, protocol_version: impl Into) -> Self { + self.protocol_version = protocol_version.into(); + self + } + + /// Set TTL attribute. + pub fn with_ttl(mut self, ttl: impl Into) -> Self { + self.ttl = ttl.into(); + self + } + + /// Set subject attribute. + pub fn with_subject(mut self, subject: impl Into) -> Self { + self.subject = subject.into(); + self + } + + /// Set producer group attribute. + pub fn with_producergroup(mut self, producergroup: impl Into) -> Self { + self.producergroup = producergroup.into(); + self + } + + /// Set unique ID attribute. + pub fn with_uniqueid(mut self, uniqueid: impl Into) -> Self { + self.uniqueid = uniqueid.into(); + self + } + + /// Set data content type attribute. + pub fn with_data_content_type(mut self, data_content_type: impl Into) -> Self { + self.data_content_type = data_content_type.into(); + self + } + + /// Build the Protobuf CloudEvent + pub fn build(&self) -> PbCloudEvent { + let mut cloud_event = PbCloudEvent::default(); + cloud_event.attributes.insert( + ProtocolKey::ENV.to_string(), + Self::build_cloud_event_attr(&self.env), + ); + cloud_event.attributes.insert( + ProtocolKey::IDC.to_string(), + Self::build_cloud_event_attr(&self.idc), + ); + cloud_event.attributes.insert( + ProtocolKey::IP.to_string(), + Self::build_cloud_event_attr(&self.ip), + ); + if let Some(ref pid) = self.pid { + cloud_event.attributes.insert( + ProtocolKey::PID.to_string(), + Self::build_cloud_event_attr(pid), + ); + } + cloud_event.attributes.insert( + ProtocolKey::SYS.to_string(), + Self::build_cloud_event_attr(&self.sys), + ); + cloud_event.attributes.insert( + ProtocolKey::LANGUAGE.to_string(), + Self::build_cloud_event_attr(&self.language), + ); + cloud_event.attributes.insert( + ProtocolKey::USERNAME.to_string(), + Self::build_cloud_event_attr(&self.user_name), + ); + cloud_event.attributes.insert( + ProtocolKey::PASSWD.to_string(), + Self::build_cloud_event_attr(&self.password), + ); + cloud_event.attributes.insert( + ProtocolKey::PROTOCOL_TYPE.to_string(), + Self::build_cloud_event_attr(&self.protocol_type), + ); + cloud_event.attributes.insert( + ProtocolKey::PROTOCOL_VERSION.to_string(), + Self::build_cloud_event_attr(&self.protocol_version), + ); + cloud_event.attributes.insert( + ProtocolKey::TTL.to_string(), + Self::build_cloud_event_attr(&self.ttl), + ); + cloud_event.attributes.insert( + ProtocolKey::SUBJECT.to_string(), + Self::build_cloud_event_attr(&self.subject), + ); + cloud_event.attributes.insert( + ProtocolKey::PRODUCERGROUP.to_string(), + Self::build_cloud_event_attr(&self.producergroup), + ); + cloud_event.attributes.insert( + ProtocolKey::UNIQUE_ID.to_string(), + Self::build_cloud_event_attr(&self.uniqueid), + ); + cloud_event.attributes.insert( + ProtocolKey::DATA_CONTENT_TYPE.to_string(), + Self::build_cloud_event_attr(&self.data_content_type), + ); + cloud_event + } + + /// Helper method to build a Protobuf CloudEvent attribute value. + fn build_cloud_event_attr(value: impl Into) -> CloudEventAttributeValue { + let mut attr_value = PbCloudEventAttributeValue::default(); + attr_value.attr = Some(PbAttr::CeString(value.into())); + attr_value + } + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/log.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/log.rs new file mode 100644 index 0000000000..87f39217bc --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/log.rs @@ -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. + */ + +pub fn init_logger() { + tracing_subscriber::fmt() + .with_thread_names(true) + .with_level(true) + .with_line_number(true) + .with_thread_ids(true) + .with_max_level(tracing::Level::INFO) + .init(); +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/model.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/model.rs new file mode 100644 index 0000000000..299c11147a --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/model.rs @@ -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. + */ + +use std::fmt::{Display, Formatter}; + +#[derive(Debug)] +pub enum EventMeshProtocolType { + CloudEvents, + EventMeshMessage, + OpenMessage, +} + +impl Display for EventMeshProtocolType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + EventMeshProtocolType::CloudEvents => { + writeln!(f, "cloudevents") + } + EventMeshProtocolType::EventMeshMessage => { + writeln!(f, "eventmeshmessage") + } + EventMeshProtocolType::OpenMessage => { + writeln!(f, "openmessage") + } + } + } +} + +impl EventMeshProtocolType { + pub fn protocol_type_name(&self) -> &'static str { + match self { + EventMeshProtocolType::CloudEvents => "cloudevents", + EventMeshProtocolType::EventMeshMessage => "eventmeshmessage", + EventMeshProtocolType::OpenMessage => "openmessage", + } + } +} + +pub mod message; + +pub(crate) mod convert; +pub mod event_clouds; +pub(crate) mod response; +pub mod subscription; diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/model/convert.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/model/convert.rs new file mode 100644 index 0000000000..8a4901f6a4 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/model/convert.rs @@ -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. + */ + +use crate::proto_cloud_event::PbCloudEvent; + +/// Trait for converting from Protobuf CloudEvent to a type `T`. +pub trait FromPbCloudEvent { + /// Convert Protobuf CloudEvent to type `T`. + /// + /// # Arguments + /// + /// * `event` - The Protobuf CloudEvent to convert from. + /// + /// # Returns + /// + /// Optional converted value of type `T`. + fn from_pb_cloud_event(event: &PbCloudEvent) -> Option; +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/model/event_clouds.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/model/event_clouds.rs new file mode 100644 index 0000000000..324ea00a94 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/model/event_clouds.rs @@ -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. + */ + + use crate::common::grpc_eventmesh_message_utils::EventMeshCloudEventUtils; + use cloudevents::Event; + + use crate::proto_cloud_event::PbCloudEvent; + + impl From for Event { + fn from(value: PbCloudEvent) -> Self { + EventMeshCloudEventUtils::switch_event_mesh_cloud_event_2_cloud_event(value) + } + } + \ No newline at end of file diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/model/message.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/model/message.rs new file mode 100644 index 0000000000..a3c42e6f06 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/model/message.rs @@ -0,0 +1,206 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#![cfg(feature = "eventmesh_message")] + +#[allow(unused_imports)] +use cloudevents::Event; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::fmt; +use std::time::{SystemTime, UNIX_EPOCH}; + +use crate::common::grpc_eventmesh_message_utils::EventMeshCloudEventUtils; +use crate::model::convert::FromPbCloudEvent; +use crate::proto_cloud_event::PbCloudEvent; + +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct EventMeshMessage { + #[serde(rename = "bizSeqNo")] + pub(crate) biz_seq_no: Option, + #[serde(rename = "uniqueId")] + pub(crate) unique_id: Option, + pub(crate) topic: Option, + pub(crate) content: Option, + pub(crate) prop: HashMap, + #[serde(rename = "createTime")] + pub(crate) create_time: u64, +} + +impl fmt::Display for EventMeshMessage { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "EventMeshMessage {{")?; + if let Some(biz_seq_no) = &self.biz_seq_no { + write!(f, " biz_seq_no: {},", biz_seq_no)?; + } + if let Some(unique_id) = &self.unique_id { + write!(f, " unique_id: {},", unique_id)?; + } + if let Some(topic) = &self.topic { + write!(f, " topic: {},", topic)?; + } + if let Some(content) = &self.content { + write!(f, " content: {},", content)?; + } + write!(f, " prop: {{")?; + for (key, value) in &self.prop { + write!(f, " {}: {},", key, value)?; + } + write!(f, " }},")?; + write!(f, " create_time: {},", self.create_time)?; + write!(f, " }}") + } +} +impl Default for EventMeshMessage { + fn default() -> Self { + Self { + biz_seq_no: None, + unique_id: None, + topic: None, + content: None, + prop: HashMap::with_capacity(0), + create_time: SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_or_else(|_err| 0u64, |time| time.as_millis() as u64), + } + } +} + +#[allow(dead_code)] +impl EventMeshMessage { + pub fn new( + biz_seq_no: impl Into, + unique_id: impl Into, + topic: impl Into, + content: impl Into, + prop: HashMap, + create_time: u64, + ) -> Self { + Self { + biz_seq_no: Some(biz_seq_no.into()), + unique_id: Some(unique_id.into()), + topic: Some(topic.into()), + content: Some(content.into()), + prop, + create_time, + } + } + + pub fn add_prop(mut self, key: String, val: String) -> Self { + self.prop.insert(key, val); + self + } + + pub fn get_prop(&self, key: &str) -> Option<&String> { + self.prop.get(key) + } + + pub fn remove_prop_if_present(mut self, key: &str) -> Self { + self.prop.remove(key); + self + } + + pub fn with_biz_seq_no(mut self, biz_seq_no: impl Into) -> Self { + self.biz_seq_no = Some(biz_seq_no.into()); + self + } + + pub fn with_unique_id(mut self, unique_id: impl Into) -> Self { + self.unique_id = Some(unique_id.into()); + self + } + + pub fn with_topic(mut self, topic: impl Into) -> Self { + self.topic = Some(topic.into()); + self + } + + pub fn with_content(mut self, content: impl Into) -> Self { + self.content = Some(content.into()); + self + } + + pub fn with_create_time(mut self, create_time: u64) -> Self { + self.create_time = create_time; + self + } +} + +impl FromPbCloudEvent for EventMeshMessage { + fn from_pb_cloud_event(event: &PbCloudEvent) -> Option { + Some(EventMeshCloudEventUtils::switch_event_mesh_cloud_event_2_event_mesh_message(event)) + } +} + +impl From for EventMeshMessage { + fn from(value: PbCloudEvent) -> Self { + EventMeshCloudEventUtils::switch_event_mesh_cloud_event_2_event_mesh_message(&value) + } +} + +#[cfg(feature = "cloud_events")] +impl From for EventMeshMessage { + fn from(value: Event) -> Self { + EventMeshCloudEventUtils::switch_cloud_event_2_event_mesh_message(value) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_default() { + let default_msg = EventMeshMessage::default(); + + assert_eq!(default_msg.biz_seq_no, None); + assert_eq!(default_msg.unique_id, None); + assert_eq!(default_msg.topic, None); + assert_eq!(default_msg.content, None); + assert!(default_msg.prop.is_empty()); + } + + #[test] + fn test_new() { + let msg = EventMeshMessage::new( + "biz_seq_123", + "unique_456", + "test_topic", + "message_content", + HashMap::new(), + 1234567890, + ); + + assert_eq!(msg.biz_seq_no, Some("biz_seq_123".to_string())); + assert_eq!(msg.unique_id, Some("unique_456".to_string())); + assert_eq!(msg.topic, Some("test_topic".to_string())); + assert_eq!(msg.content, Some("message_content".to_string())); + assert!(msg.prop.is_empty()); + assert_eq!(msg.create_time, 1234567890); + } + + #[test] + fn test_add_prop() { + let mut msg = EventMeshMessage::default(); + + msg = msg.add_prop("key1".to_string(), "value1".to_string()); + msg = msg.add_prop("key2".to_string(), "value2".to_string()); + + assert_eq!(msg.get_prop("key1"), Some(&"value1".to_string())); + assert_eq!(msg.get_prop("key2"), Some(&"value2".to_string())); + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/model/response.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/model/response.rs new file mode 100644 index 0000000000..6e269623cb --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/model/response.rs @@ -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. + */ + +use std::fmt::{Display, Formatter}; + +use serde::Deserialize; + +#[derive(Debug, Deserialize, Default)] +pub struct EventMeshResponse { + #[serde(rename = "respCode")] + resp_code: Option, + + #[serde(rename = "respMsg")] + resp_msg: Option, + + #[serde(rename = "respTime")] + resp_time: Option, +} + +impl EventMeshResponse { + pub fn new( + resp_code: Option, + resp_msg: Option, + resp_time: Option, + ) -> Self { + Self { + resp_code, + resp_msg, + resp_time, + } + } +} + +impl Display for EventMeshResponse { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "EventMeshResponse[")?; + if let Some(ref code) = self.resp_code { + write!(f, "code={code},")?; + } + if let Some(ref msg) = self.resp_msg { + write!(f, "message={msg},")?; + } + if let Some(time) = self.resp_time { + write!(f, "response time={time},")?; + } + write!(f, "]")?; + Ok(()) + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/model/subscription.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/model/subscription.rs new file mode 100644 index 0000000000..a31cd3b90d --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/model/subscription.rs @@ -0,0 +1,277 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +use std::collections::HashMap; +use std::fmt; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; + +use serde::{Deserialize, Serialize}; + +use crate::error::EventMeshError; + +#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Hash, Clone)] +pub struct SubscriptionItem { + pub topic: String, + pub mode: SubscriptionMode, + #[serde(rename = "type")] + pub type_: SubscriptionType, +} + +impl SubscriptionItem { + pub fn new(topic: impl Into, mode: SubscriptionMode, type_: SubscriptionType) -> Self { + SubscriptionItem { + topic: topic.into(), + mode, + type_, + } + } +} + +impl fmt::Display for SubscriptionItem { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "SubscriptionItem {{ topic: {}, mode: {}, type: {} }}", + self.topic, self.mode, self.type_ + ) + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Hash)] +pub enum SubscriptionMode { + BROADCASTING, + CLUSTERING, + UNRECOGNIZED, +} + +impl Display for SubscriptionMode { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + writeln!(f, "{}", self.to_string()) + } +} + +impl SubscriptionMode { + pub fn to_string(&self) -> &'static str { + match self { + SubscriptionMode::BROADCASTING => "BROADCASTING", + SubscriptionMode::CLUSTERING => "CLUSTERING", + SubscriptionMode::UNRECOGNIZED => "UNRECOGNIZED", + } + } + + fn from_str_inner(input: &str) -> Result { + match input { + "BROADCASTING" => Ok(SubscriptionMode::BROADCASTING), + "CLUSTERING" => Ok(SubscriptionMode::CLUSTERING), + "UNRECOGNIZED" => Ok(SubscriptionMode::UNRECOGNIZED), + _ => Err(EventMeshError::EventMeshFromStrError(format!( + "{} can not parse to SubscriptionMode", + input + ))), + } + } +} + +impl FromStr for SubscriptionMode { + type Err = EventMeshError; + + fn from_str(s: &str) -> Result { + Self::from_str_inner(s) + } +} + +impl TryFrom for SubscriptionMode { + type Error = EventMeshError; + + fn try_from(value: String) -> Result { + Self::from_str_inner(value.as_str()) + } +} + +impl TryFrom<&'static str> for SubscriptionMode { + type Error = EventMeshError; + + fn try_from(value: &'static str) -> Result { + Self::from_str_inner(value) + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Hash)] +pub enum SubscriptionType { + SYNC, + ASYNC, + UNRECOGNIZED, +} + +impl Display for SubscriptionType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + writeln!(f, "{}", self.to_string()) + } +} + +impl SubscriptionType { + pub fn to_string(&self) -> &'static str { + match self { + SubscriptionType::SYNC => "SYNC", + SubscriptionType::ASYNC => "ASYNC", + SubscriptionType::UNRECOGNIZED => "UNRECOGNIZED", + } + } + + fn from_str_inner(s: &str) -> Result { + match s { + "SYNC" => Ok(SubscriptionType::SYNC), + "ASYNC" => Ok(SubscriptionType::ASYNC), + "UNRECOGNIZED" => Ok(SubscriptionType::UNRECOGNIZED), + _ => Err(EventMeshError::EventMeshFromStrError(format!( + "{} can not parse to SubscriptionMode", + s + ))), + } + } +} + +impl FromStr for SubscriptionType { + type Err = EventMeshError; + + fn from_str(s: &str) -> Result { + Self::from_str_inner(s) + } +} + +impl TryFrom for SubscriptionType { + type Error = EventMeshError; + + fn try_from(value: String) -> Result { + Self::from_str_inner(value.as_str()) + } +} + +impl TryFrom<&'static str> for SubscriptionType { + type Error = EventMeshError; + + fn try_from(value: &'static str) -> Result { + Self::from_str_inner(value) + } +} + +#[derive(Debug)] +pub(crate) struct SubscriptionItemWrapper { + pub(crate) subscription_item: SubscriptionItem, + pub(crate) url: String, +} + +impl Display for SubscriptionItemWrapper { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + writeln!( + f, + "SubscriptionItem={},url={}", + self.subscription_item, self.url + ) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SubscriptionReply { + #[serde(rename = "producerGroup")] + pub(crate) producer_group: String, + pub(crate) topic: String, + pub(crate) content: String, + pub(crate) ttl: String, + #[serde(rename = "uniqueId")] + pub(crate) unique_id: String, + #[serde(rename = "seqNum")] + pub(crate) seq_num: String, + pub(crate) tag: Option, + pub(crate) properties: HashMap, +} + +impl SubscriptionReply { + pub const SUB_TYPE: &'static str = "subscription_reply"; + + pub fn new( + producer_group: String, + topic: String, + content: String, + ttl: String, + unique_id: String, + seq_num: String, + tag: Option, + properties: HashMap, + ) -> Self { + Self { + producer_group, + topic, + content, + ttl, + unique_id, + seq_num, + tag, + properties, + } + } +} + +impl ToString for SubscriptionReply { + fn to_string(&self) -> String { + format!( + "SubscriptionReply {{ + producer_group: {:?}, + topic: {:?}, + content: {:?}, + ttl: {:?}, + unique_id: {:?}, + seq_num: {:?}, + tag: {:?}, + properties: {:?} + }}", + self.producer_group, + self.topic, + self.content, + self.ttl, + self.unique_id, + self.seq_num, + self.tag, + self.properties + ) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct HeartbeatItem { + pub(crate) topic: String, + pub(crate) url: String, +} + +impl HeartbeatItem { + pub fn new(topic: String, url: String) -> Self { + Self { topic, url } + } +} + +impl Display for HeartbeatItem { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + writeln!( + f, + "HeartbeatItem {{ + topic: {}, + url: {} + }}", + self.url, self.topic + ) + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/net.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/net.rs new file mode 100644 index 0000000000..1a1b09f320 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/net.rs @@ -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. + */ +#![allow(unused_imports)] +pub use crate::net::grpc::grpc_client::GrpcClient; +pub use crate::net::grpc::grpc_client::SubscribeStreamKeeper; +mod grpc; diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/net/grpc.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/net/grpc.rs new file mode 100644 index 0000000000..54ddb9a238 --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/net/grpc.rs @@ -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. + */ +pub(crate) mod grpc_client; diff --git a/eventmesh-sdks/eventmesh-sdk-rust/src/net/grpc/grpc_client.rs b/eventmesh-sdks/eventmesh-sdk-rust/src/net/grpc/grpc_client.rs new file mode 100644 index 0000000000..8d4a376f0b --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/src/net/grpc/grpc_client.rs @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +use std::time::Duration; + +use tokio::sync::mpsc; +use tokio::sync::mpsc::Sender; +use tonic::codegen::tokio_stream::wrappers::ReceiverStream; +use tonic::transport::{Channel, Endpoint, Uri}; +use tonic::{Request, Streaming}; + +use crate::common::ProtocolKey; +use crate::config::EventMeshGrpcClientConfig; +use crate::error::EventMeshError; +use crate::error::EventMeshError::EventMeshRemote; +use crate::grpc::pb::cloud_events::cloud_event::cloud_event_attribute_value::Attr; +use crate::grpc::pb::cloud_events::consumer_service_client::ConsumerServiceClient; +use crate::grpc::pb::cloud_events::heartbeat_service_client::HeartbeatServiceClient; +use crate::grpc::pb::cloud_events::publisher_service_client::PublisherServiceClient; +use crate::proto_cloud_event::{PbCloudEvent, PbCloudEventBatch}; + +pub struct SubscribeStreamKeeper { + pub(crate) sender: Sender, +} + +impl SubscribeStreamKeeper { + pub(crate) fn new(sender: Sender) -> Self { + Self { sender } + } +} + +#[derive(Clone)] +pub struct GrpcClient { + publisher_inner: PublisherServiceClient, + consumer_inner: ConsumerServiceClient, + heartbeat_inner: HeartbeatServiceClient, +} + +impl GrpcClient { + pub fn new(grpc_config: &EventMeshGrpcClientConfig) -> crate::Result { + #[cfg(feature = "tls")] + let scheme = { "https" }; + + #[cfg(not(feature = "tls"))] + let scheme = { + if let Some(tls) = grpc_config.use_tls { + if tls { + "https" + } else { + "http" + } + } else { + "http" + } + }; + let url = format!("{}:{}", grpc_config.server_addr, grpc_config.server_port); + let endpoint_uri = Uri::builder() + .scheme(scheme) + .authority(url) + .path_and_query("/") + .build()?; + let endpoint = Endpoint::from(endpoint_uri) + .connect_timeout(Duration::from_millis(10000)) + .keep_alive_while_idle(true) + .tcp_nodelay(true) + .tcp_keepalive(Some(Duration::from_secs(100))); + + let channel = endpoint.connect_lazy(); + let publisher_service_client = PublisherServiceClient::new(channel.clone()); + let consumer_service_client = ConsumerServiceClient::new(channel.clone()); + let heartbeat_inner_client = HeartbeatServiceClient::new(channel); + Ok(Self { + publisher_inner: publisher_service_client, + consumer_inner: consumer_service_client, + heartbeat_inner: heartbeat_inner_client, + }) + } + + pub(crate) async fn publish_inner( + &mut self, + cloud_event: PbCloudEvent, + ) -> crate::Result { + let result = self + .publisher_inner + .publish(cloud_event) + .await + .map_err(|e| EventMeshError::GRpcStatus(e))? + .into_inner(); + Ok(result) + } + + pub(crate) async fn batch_publish_inner( + &mut self, + cloud_events: PbCloudEventBatch, + ) -> crate::Result { + let result = self + .publisher_inner + .batch_publish(cloud_events) + .await + .map_err(|e| EventMeshError::GRpcStatus(e))? + .into_inner(); + Ok(result) + } + + pub(crate) async fn request_reply_inner( + &mut self, + cloud_event: PbCloudEvent, + time_out: u64, + ) -> crate::Result { + let future_task = self.publisher_inner.request_reply(cloud_event); + let result = tokio::time::timeout(Duration::from_millis(time_out), future_task).await; + match result { + Ok(Ok(value)) => { + let event = value.into_inner(); + if let Some(code) = event.attributes.get(ProtocolKey::GRPC_RESPONSE_CODE) { + if let Some(code_num) = &code.attr { + match code_num { + Attr::CeString(cd) if cd != "0" => { + if let Some(msg) = + event.attributes.get(ProtocolKey::GRPC_RESPONSE_MESSAGE) + { + if let Some(msg_inner) = &msg.attr { + match msg_inner { + Attr::CeString(msg) => { + return Err(EventMeshRemote(msg.to_string()).into()); + } + _ => {} + } + } + } + return Err( + EventMeshRemote("EventMesh remote error".to_string()).into() + ); + } + _ => {} + } + } + } + Ok(event) + } + Ok(Err(err)) => Err(EventMeshError::GRpcStatus(err).into()), + Err(_) => Err(EventMeshError::EventMeshLocal("Request reply error".to_string()).into()), + } + } + + pub(crate) async fn subscribe_webhook_inner( + &mut self, + cloud_event: PbCloudEvent, + ) -> crate::Result { + let result = self + .consumer_inner + .subscribe(cloud_event) + .await + .map_err(|e| EventMeshError::GRpcStatus(e))? + .into_inner(); + Ok(result) + } + + pub(crate) async fn subscribe_bi_inner( + &mut self, + cloud_event: PbCloudEvent, + ) -> crate::Result<(SubscribeStreamKeeper, Streaming)> { + let (sender, receiver) = mpsc::channel::(16); + sender.send(cloud_event).await?; + let streaming = self + .consumer_inner + .subscribe_stream(Request::new(ReceiverStream::new(receiver))) + .await + .map_err(|e| EventMeshError::GRpcStatus(e))? + .into_inner(); + Ok((SubscribeStreamKeeper::new(sender), streaming)) + } + + pub(crate) async fn unsubscribe_inner( + &mut self, + cloud_event: PbCloudEvent, + ) -> crate::Result { + let result = self + .consumer_inner + .unsubscribe(cloud_event) + .await + .map_err(|e| EventMeshError::GRpcStatus(e))? + .into_inner(); + Ok(result) + } + + pub(crate) async fn heartbeat_inner( + &mut self, + cloud_event: PbCloudEvent, + ) -> crate::Result { + let result = self + .heartbeat_inner + .heartbeat(Request::new(cloud_event)) + .await + .map_err(|e| EventMeshError::GRpcStatus(e))? + .into_inner(); + Ok(result) + } +} diff --git a/eventmesh-sdks/eventmesh-sdk-rust/tests/eventmesh_message_utils_test.rs b/eventmesh-sdks/eventmesh-sdk-rust/tests/eventmesh_message_utils_test.rs new file mode 100644 index 0000000000..fc523880ca --- /dev/null +++ b/eventmesh-sdks/eventmesh-sdk-rust/tests/eventmesh_message_utils_test.rs @@ -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. + */ + +use eventmesh::common::grpc_eventmesh_message_utils::{EventMeshCloudEventUtils, ProtoSupport}; +use eventmesh::config::EventMeshGrpcClientConfig; +use eventmesh::model::EventMeshProtocolType; +use eventmesh::proto_cloud_event::PbAttr; + +#[test] +fn test_proto_support_is_text_content() { + assert!(ProtoSupport::is_text_content("text/plain")); + assert!(ProtoSupport::is_text_content("text/html")); + assert!(ProtoSupport::is_text_content("application/json")); + assert!(ProtoSupport::is_text_content("application/xml")); + assert!(!ProtoSupport::is_text_content("application/json+foo")); + assert!(!ProtoSupport::is_text_content("application/xml+bar")); + assert!(!ProtoSupport::is_text_content("")); + assert!(!ProtoSupport::is_text_content("application/octet-stream")); +} + +#[test] +fn test_proto_support_is_proto_content() { + assert!(ProtoSupport::is_proto_content("application/protobuf")); + assert!(!ProtoSupport::is_proto_content("")); + assert!(!ProtoSupport::is_proto_content("application/json")); + assert!(!ProtoSupport::is_proto_content("text/plain")); +} + +#[test] +fn test_event_mesh_cloud_event_utils_build_common_cloud_event_attributes() { + let client_config = EventMeshGrpcClientConfig::default() + .set_env("test_env".to_string()) + .set_idc("test_idc".to_string()); + let protocol_type = EventMeshProtocolType::CloudEvents; + let attribute_map = EventMeshCloudEventUtils::build_common_cloud_event_attributes( + &client_config, + protocol_type, + ); + + assert_eq!( + *attribute_map.get("env").map(|attr| &attr.attr).unwrap(), + Some(PbAttr::CeString("test_env".to_string())) + ); + assert_eq!( + *attribute_map.get("idc").map(|attr| &attr.attr).unwrap(), + Some(PbAttr::CeString("test_idc".to_string())) + ); +} 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 index 3abb64a80a..96e2b84845 100644 --- 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 @@ -21,41 +21,40 @@ import org.apache.eventmesh.api.acl.AclService; import org.apache.eventmesh.api.exception.AclException; - public class AclServiceImpl implements AclService { @Override public void init() throws AclException { - //TODO + // TODO } @Override public void start() throws AclException { - //TODO + // TODO } @Override public void shutdown() throws AclException { - //TODO + // TODO } @Override public void doAclCheckInConnect(AclProperties aclProperties) throws AclException { - //TODO + // TODO } @Override public void doAclCheckInHeartbeat(AclProperties aclProperties) throws AclException { - //TODO + // TODO } @Override public void doAclCheckInSend(AclProperties aclProperties) throws AclException { - //TODO + // TODO } @Override public void doAclCheckInReceive(AclProperties aclProperties) throws AclException { - //TODO + // TODO } } diff --git a/eventmesh-security-plugin/eventmesh-security-acl/src/test/java/org/apache/eventmesh/acl/impl/AclServiceImplTest.java b/eventmesh-security-plugin/eventmesh-security-acl/src/test/java/org/apache/eventmesh/acl/impl/AclServiceImplTest.java index 7e0bb020a2..2108331c24 100644 --- a/eventmesh-security-plugin/eventmesh-security-acl/src/test/java/org/apache/eventmesh/acl/impl/AclServiceImplTest.java +++ b/eventmesh-security-plugin/eventmesh-security-acl/src/test/java/org/apache/eventmesh/acl/impl/AclServiceImplTest.java @@ -19,82 +19,52 @@ import org.apache.eventmesh.api.acl.AclProperties; import org.apache.eventmesh.api.acl.AclService; -import org.apache.eventmesh.api.exception.AclException; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class AclServiceImplTest { private static AclService service; - @BeforeClass + @BeforeAll public static void beforeClass() { service = new AclServiceImpl(); } @Test public void testInit() { - try { - service.init(); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(service::init); } @Test public void testStart() { - try { - service.start(); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(service::start); } @Test public void testShutdown() { - try { - service.shutdown(); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(service::shutdown); } @Test public void testDoAclCheckInConnect() { - try { - service.doAclCheckInConnect(new AclProperties()); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> service.doAclCheckInConnect(new AclProperties())); } @Test public void testDoAclCheckInHeartbeat() { - try { - service.doAclCheckInHeartbeat(new AclProperties()); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> service.doAclCheckInHeartbeat(new AclProperties())); } @Test public void testDoAclCheckInSend() { - try { - service.doAclCheckInSend(new AclProperties()); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> service.doAclCheckInSend(new AclProperties())); } @Test public void testDoAclCheckInReceive() { - try { - service.doAclCheckInReceive(new AclProperties()); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> service.doAclCheckInReceive(new AclProperties())); } } diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclProperties.java b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclProperties.java index 2338f05860..d340f12888 100644 --- a/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclProperties.java +++ b/eventmesh-security-plugin/eventmesh-security-api/src/main/java/org/apache/eventmesh/api/acl/AclProperties.java @@ -30,6 +30,7 @@ public class AclProperties { private Integer requestCode; private String requestURI; private String token; + private String version; private Map extendedFields = new ConcurrentHashMap<>(); public String getClientIp() { @@ -104,5 +105,11 @@ public Object getExtendedField(String key) { return extendedFields.get(key); } + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } } 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 index 7bf56f0c3c..606a91b949 100644 --- 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 @@ -26,4 +26,5 @@ public class AclPropertyKeys { public static final String TOPIC = "topic"; public static final String REQUEST_CODE = "requestCode"; public static final String REQUEST_URI = "requestURI"; + public static final String CLIENT_VERSION = "clientVersion"; } 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 index 88d7f56818..3217aaccb8 100644 --- 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 @@ -21,7 +21,6 @@ import org.apache.eventmesh.spi.EventMeshExtensionType; import org.apache.eventmesh.spi.EventMeshSPI; - /** * AclService */ diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/acl/AclServiceTest.java b/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/acl/AclServiceTest.java index 7f0a5b1b4a..36f1188c77 100644 --- a/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/acl/AclServiceTest.java +++ b/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/acl/AclServiceTest.java @@ -19,10 +19,9 @@ import org.apache.eventmesh.api.exception.AclException; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class AclServiceTest { @@ -66,72 +65,44 @@ public void doAclCheckInReceive(AclProperties aclProperties) throws AclException private static AclService service; - @BeforeClass + @BeforeAll public static void beforeClass() { service = new DemoAclService(); } @Test public void testInit() { - try { - service.init(); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(service::init); } @Test public void testStart() { - try { - service.start(); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(service::start); } @Test public void testShutdown() { - try { - service.shutdown(); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(service::shutdown); } @Test public void testDoAclCheckInConnect() { - try { - service.doAclCheckInConnect(new AclProperties()); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> service.doAclCheckInConnect(new AclProperties())); } @Test public void testDoAclCheckInHeartbeat() { - try { - service.doAclCheckInHeartbeat(new AclProperties()); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> service.doAclCheckInHeartbeat(new AclProperties())); } @Test public void testDoAclCheckInSend() { - try { - service.doAclCheckInSend(new AclProperties()); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> service.doAclCheckInSend(new AclProperties())); } @Test public void testDoAclCheckInReceive() { - try { - service.doAclCheckInReceive(new AclProperties()); - } catch (AclException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> service.doAclCheckInReceive(new AclProperties())); } } diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/auth/AuthServiceTest.java b/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/auth/AuthServiceTest.java index d0e3b8bf6b..4dcf88ead3 100644 --- a/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/auth/AuthServiceTest.java +++ b/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/auth/AuthServiceTest.java @@ -21,9 +21,9 @@ import java.util.Map; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class AuthServiceTest { @@ -52,45 +52,29 @@ public Map getAuthParams() throws AuthException { private static AuthService service; - @BeforeClass + @BeforeAll public static void beforeClass() { service = new DemoAuthService(); } @Test public void testInit() { - try { - service.init(); - } catch (AuthException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(service::init); } @Test public void testStart() { - try { - service.start(); - } catch (AuthException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(service::start); } @Test public void testShutdown() { - try { - service.shutdown(); - } catch (AuthException e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(service::shutdown); } @Test public void testGetAuthParams() { - try { - Map authParams = service.getAuthParams(); - Assert.assertNull(authParams); - } catch (AuthException e) { - Assert.fail(e.getMessage()); - } + Map authParams = service.getAuthParams(); + Assertions.assertNull(authParams); } } diff --git a/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/exception/AclExceptionTest.java b/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/exception/AclExceptionTest.java index 9f4448c40b..94ca153480 100644 --- a/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/exception/AclExceptionTest.java +++ b/eventmesh-security-plugin/eventmesh-security-api/src/test/java/org/apache/eventmesh/api/exception/AclExceptionTest.java @@ -17,30 +17,20 @@ package org.apache.eventmesh.api.exception; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class AclExceptionTest { @Test public void testConstructWithMsg() { - try { - new AclException("test"); - - new AclException(null); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> new AclException("test")); + Assertions.assertDoesNotThrow(() -> new AclException(null)); } @Test public void testConstructWithMsgAndExption() { - try { - new AclException("test", new Exception("test1")); - - new AclException(null, null); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } + Assertions.assertDoesNotThrow(() -> new AclException("test", new Exception("test1"))); + Assertions.assertDoesNotThrow(() -> new AclException(null, null)); } } diff --git a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/test/java/org/apache/eventmesh/auth/http/basic/config/AuthConfigsTest.java b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/test/java/org/apache/eventmesh/auth/http/basic/config/AuthConfigsTest.java index faf116da76..2cfad09e46 100644 --- a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/test/java/org/apache/eventmesh/auth/http/basic/config/AuthConfigsTest.java +++ b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/test/java/org/apache/eventmesh/auth/http/basic/config/AuthConfigsTest.java @@ -21,8 +21,8 @@ import org.apache.eventmesh.auth.http.basic.impl.AuthHttpBasicService; import org.apache.eventmesh.spi.EventMeshExtensionFactory; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class AuthConfigsTest { @@ -36,7 +36,7 @@ public void getConfigWhenAuthHttpBasicServiceInit() { } private void assertConfig(AuthConfigs config) { - Assert.assertEquals(config.getUsername(), "username-success!!!"); - Assert.assertEquals(config.getPassword(), "password-success!!!"); + Assertions.assertEquals(config.getUsername(), "username-success!!!"); + Assertions.assertEquals(config.getPassword(), "password-success!!!"); } } diff --git a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/test/java/org/apache/eventmesh/auth/http/basic/impl/AuthHttpBasicServiceTest.java b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/test/java/org/apache/eventmesh/auth/http/basic/impl/AuthHttpBasicServiceTest.java index 0a90610a95..cb5f5d81bb 100644 --- a/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/test/java/org/apache/eventmesh/auth/http/basic/impl/AuthHttpBasicServiceTest.java +++ b/eventmesh-security-plugin/eventmesh-security-auth-http-basic/src/test/java/org/apache/eventmesh/auth/http/basic/impl/AuthHttpBasicServiceTest.java @@ -17,21 +17,20 @@ package org.apache.eventmesh.auth.http.basic.impl; - import org.apache.eventmesh.api.auth.AuthService; import org.apache.eventmesh.spi.EventMeshExtensionFactory; import java.util.Map; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; public class AuthHttpBasicServiceTest { private static AuthHttpBasicService service; - @BeforeClass + @BeforeAll public static void beforeClass() { service = (AuthHttpBasicService) EventMeshExtensionFactory.getExtension( AuthService.class, "auth-http-basic"); @@ -39,34 +38,20 @@ public static void beforeClass() { @Test public void testInitAndGetAuthParams() { - try { - service.init(); - Map authParams = service.getAuthParams(); - String authorization = authParams.get("Authorization"); - Assert.assertNotNull(authorization); - Assert.assertTrue(authorization.length() > 5); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } + service.init(); + Map authParams = service.getAuthParams(); + String authorization = authParams.get("Authorization"); + Assertions.assertNotNull(authorization); + Assertions.assertTrue(authorization.length() > 5); } @Test public void testStart() { - try { - service.start(); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } - + Assertions.assertDoesNotThrow(service::start); } @Test public void testShutdown() { - try { - service.shutdown(); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } - + Assertions.assertDoesNotThrow(service::shutdown); } } diff --git a/eventmesh-security-plugin/eventmesh-security-auth-token/src/main/java/org/apache/eventmesh/auth/token/impl/auth/AuthTokenUtils.java b/eventmesh-security-plugin/eventmesh-security-auth-token/src/main/java/org/apache/eventmesh/auth/token/impl/auth/AuthTokenUtils.java index 0bf004c626..ac55f88c9d 100644 --- a/eventmesh-security-plugin/eventmesh-security-auth-token/src/main/java/org/apache/eventmesh/auth/token/impl/auth/AuthTokenUtils.java +++ b/eventmesh-security-plugin/eventmesh-security-auth-token/src/main/java/org/apache/eventmesh/auth/token/impl/auth/AuthTokenUtils.java @@ -21,6 +21,7 @@ import org.apache.eventmesh.api.exception.AclException; import org.apache.eventmesh.common.config.CommonConfiguration; import org.apache.eventmesh.common.utils.ConfigurationContextUtil; +import org.apache.eventmesh.common.utils.TypeUtils; import org.apache.commons.lang3.StringUtils; @@ -40,12 +41,11 @@ import io.jsonwebtoken.JwtParser; import io.jsonwebtoken.Jwts; - public class AuthTokenUtils { public static void authTokenByPublicKey(AclProperties aclProperties) { - String token = aclProperties.getToken(); + String token = aclProperties.getToken(); if (StringUtils.isNotBlank(token)) { if (!authAccess(aclProperties)) { throw new AclException("group:" + aclProperties.getExtendedField("group ") + " has no auth to access the topic:" @@ -87,9 +87,7 @@ public static void authTokenByPublicKey(AclProperties aclProperties) { } } else { - { - throw new AclException("invalid token!"); - } + throw new AclException("invalid token!"); } } @@ -131,9 +129,7 @@ public static void helloTaskAuthTokenByPublicKey(AclProperties aclProperties) { throw new AclException("invalid token!", e); } } else { - { - throw new AclException("invalid token!"); - } + throw new AclException("invalid token!"); } } @@ -141,14 +137,15 @@ public static boolean authAccess(AclProperties aclProperties) { String topic = aclProperties.getTopic(); - Set groupTopics = (Set) aclProperties.getExtendedField("topics"); + Object topics = aclProperties.getExtendedField("topics"); - if (groupTopics.contains(topic)) { - return true; - } else { + if (!(topics instanceof Set)) { return false; } + Set groupTopics = TypeUtils.castSet(topics, String.class); + + return groupTopics.contains(topic); } } 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 index 5a65e43a58..cc47f5ef9f 100644 --- a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionFactory.java +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionFactory.java @@ -29,9 +29,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; - import lombok.extern.slf4j.Slf4j; /** @@ -43,65 +43,84 @@ public class EventMeshExtensionFactory { private static final List EXTENSION_CLASS_LOADERS = new ArrayList<>(); - private static final ConcurrentHashMap EXTENSION_INSTANCE_CACHE = new ConcurrentHashMap<>(16); + private static final ConcurrentHashMap EXTENSION_INSTANCE_CACHE = new ConcurrentHashMap<>(16); static { EXTENSION_CLASS_LOADERS.add(MetaInfExtensionClassLoader.getInstance()); EXTENSION_CLASS_LOADERS.add(JarExtensionClassLoader.getInstance()); } - private EventMeshExtensionFactory() { } /** - * @param extensionType extension plugin class type - * @param extensionName extension instance name - * @param the type of the plugin + * Get an instance of an extension plugin. + * + * @param extensionClass 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"); + public static T getExtension(Class extensionClass, String extensionName) { + if (extensionClass == null) { + throw new ExtensionException("extensionClass 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)); + if (!extensionClass.isInterface() || !extensionClass.isAnnotationPresent(EventMeshSPI.class)) { + throw new ExtensionException(String.format("extensionClass:%s is invalided", extensionClass)); } - EventMeshSPI eventMeshSPIAnnotation = extensionType.getAnnotation(EventMeshSPI.class); + EventMeshSPI eventMeshSPIAnnotation = extensionClass.getAnnotation(EventMeshSPI.class); if (eventMeshSPIAnnotation.isSingleton()) { - return getSingletonExtension(extensionType, extensionName); + return getSingletonExtension(extensionClass, eventMeshSPIAnnotation, extensionName); } - return getPrototypeExtension(extensionType, extensionName); + return getPrototypeExtension(extensionClass, extensionName); } + /** + * Get a singleton instance of an extension plugin. + * + * @param extensionClass the type of the extension plugin + * @param spi the type of the spi + * @param extensionInstanceName the name of the extension instance + * @param the type of the extension plugin + * @return a singleton instance of the extension plugin + */ @SuppressWarnings("unchecked") - private static T getSingletonExtension(Class extensionType, String extensionInstanceName) { - return (T) EXTENSION_INSTANCE_CACHE.computeIfAbsent(extensionInstanceName, name -> { - Class extensionInstanceClass = getExtensionInstanceClass(extensionType, extensionInstanceName); + private static T getSingletonExtension(Class extensionClass, EventMeshSPI spi, String extensionInstanceName) { + return (T) EXTENSION_INSTANCE_CACHE.computeIfAbsent(new Extension(spi, extensionInstanceName), name -> { + Class extensionInstanceClass = getExtensionInstanceClass(extensionClass, extensionInstanceName); if (extensionInstanceClass == null) { + log.warn("Get extension instance class {} is null", extensionClass.getName()); return null; } try { T extensionInstance = extensionInstanceClass.getDeclaredConstructor().newInstance(); ConfigService.getInstance().populateConfigForObject(extensionInstance); - log.info("initialize extension instance success, extensionType: {}, extensionInstanceName: {}", - extensionType, extensionInstanceName); + log.info("initialize extension instance success, extensionClass: {}, extensionInstanceName: {}", + extensionClass, extensionInstanceName); return extensionInstance; } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { throw new ExtensionException("Extension initialize error", e); } catch (NoSuchFieldException | IOException e) { - log.error("initialize extension instance config failed, extensionType: {}, extensionInstanceName: {}", - extensionType, extensionInstanceName, e); + log.error("initialize extension instance config failed, extensionClass: {}, extensionInstanceName: {}", + extensionClass, extensionInstanceName, e); throw new ExtensionException("Extension initialize error", e); } }); } + /** + * Get a new instance of an extension plugin. + * + * @param extensionType the type of the extension plugin + * @param extensionInstanceName the name of the extension instance + * @param the type of the extension plugin + * @return a new instance of the extension plugin + */ private static T getPrototypeExtension(Class extensionType, String extensionInstanceName) { Class extensionInstanceClass = getExtensionInstanceClass(extensionType, extensionInstanceName); if (extensionInstanceClass == null) { @@ -123,6 +142,14 @@ private static T getPrototypeExtension(Class extensionType, String extens } } + /** + * Get the class of an extension instance. + * + * @param extensionType the type of the extension instance + * @param extensionInstanceName the name of the extension instance + * @param the type of the extension instance + * @return the class of the extension instance + */ @SuppressWarnings("unchecked") private static Class getExtensionInstanceClass(Class extensionType, String extensionInstanceName) { for (ExtensionClassLoader extensionClassLoader : EXTENSION_CLASS_LOADERS) { @@ -134,4 +161,33 @@ private static Class getExtensionInstanceClass(Class extensionType, St } return null; } + + private static class Extension { + + private EventMeshSPI spi; + + private String extensionInstanceName; + + public Extension(EventMeshSPI spi, String extensionInstanceName) { + this.spi = spi; + this.extensionInstanceName = extensionInstanceName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof Extension)) { + return false; + } + Extension extension = (Extension) o; + return Objects.equals(spi, extension.spi) && Objects.equals(extensionInstanceName, extension.extensionInstanceName); + } + + @Override + public int hashCode() { + return Objects.hash(spi, extensionInstanceName); + } + } } 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 index b07bd6e968..f76379f9e8 100644 --- a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionType.java +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionType.java @@ -21,14 +21,20 @@ * An Extension can be defined by extensionTypeName and extensionInstanceName */ public enum EventMeshExtensionType { + UNKNOWN("unknown"), CONNECTOR("connector"), STORAGE("storage"), - REGISTRY("registry"), + META("metaStorage"), SECURITY("security"), PROTOCOL("protocol"), METRICS("metrics"), TRACE("trace"), + JDBC_CDC_ENGINE("jdbc_cdc_engine"), + JDBC_SNAPSHOT_ENGINE("jdbc_snapshot_engine"), + JDBC_DATABASE_DIALECT("jdbc_database_dialect"), + OFFSETMGMT("offsetMgmt"), + RETRY("retry"), ; private final String 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 index 850340f206..7722d59613 100644 --- a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshSPI.java +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshSPI.java @@ -44,4 +44,3 @@ EventMeshExtensionType eventMeshExtensionType(); } - 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 index a73270bfe3..0680831f5a 100644 --- 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 @@ -35,7 +35,6 @@ import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; - import com.google.common.base.Joiner; import com.google.common.collect.Lists; @@ -113,8 +112,8 @@ private List loadJarPathFromResource(String pluginPath) { pluginUrls.addAll(loadJarPathFromResource(file.getPath())); } } - // Sort the path here just to guarantee load the ConsumeMessageConcurrentlyService - // defined in EventMesh rather than defined in rocketmq + // 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; } 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 index dd00dff226..0884df230f 100644 --- 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 @@ -28,7 +28,6 @@ import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; - import lombok.extern.slf4j.Slf4j; /** 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 index 55b3156c78..5837bdcff2 100644 --- a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/EventMeshExtensionFactoryTest.java +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/EventMeshExtensionFactoryTest.java @@ -17,11 +17,12 @@ package org.apache.eventmesh.spi; +import org.apache.eventmesh.spi.example.TestAnotherSingletonExtension; import org.apache.eventmesh.spi.example.TestPrototypeExtension; import org.apache.eventmesh.spi.example.TestSingletonExtension; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class EventMeshExtensionFactoryTest { @@ -29,35 +30,26 @@ public class EventMeshExtensionFactoryTest { public void testGetSingletonExtension() { TestSingletonExtension extensionA = EventMeshExtensionFactory.getExtension(TestSingletonExtension.class, "singletonExtension"); TestSingletonExtension extensionB = EventMeshExtensionFactory.getExtension(TestSingletonExtension.class, "singletonExtension"); - Assert.assertSame(extensionA, extensionB); + Assertions.assertSame(extensionA, extensionB); + + TestAnotherSingletonExtension singletonExtension = EventMeshExtensionFactory.getExtension(TestAnotherSingletonExtension.class, + "singletonExtension"); + Assertions.assertNotNull(singletonExtension); + TestSingletonExtension singletonExtension1 = EventMeshExtensionFactory.getExtension(TestSingletonExtension.class, "singletonExtension"); + Assertions.assertNotNull(singletonExtension1); + } @Test public void testGetPrototypeExtension() { TestPrototypeExtension prototypeExtensionA = EventMeshExtensionFactory.getExtension(TestPrototypeExtension.class, "prototypeExtension"); TestPrototypeExtension prototypeExtensionB = EventMeshExtensionFactory.getExtension(TestPrototypeExtension.class, "prototypeExtension"); - Assert.assertNotSame(prototypeExtensionA, prototypeExtensionB); + Assertions.assertNotSame(prototypeExtensionA, prototypeExtensionB); } @Test public void testGetExtension() { - ExtensionException exception = null; - try { - EventMeshExtensionFactory.getExtension(null, "eventmesh"); - } catch (Exception ex) { - if (ex instanceof ExtensionException) { - exception = (ExtensionException) ex; - } - } - Assert.assertNotNull(exception); - exception = null; - try { - EventMeshExtensionFactory.getExtension(TestPrototypeExtension.class, null); - } catch (Exception ex) { - if (ex instanceof ExtensionException) { - exception = (ExtensionException) ex; - } - } - Assert.assertNotNull(exception); + Assertions.assertThrows(ExtensionException.class, () -> EventMeshExtensionFactory.getExtension(null, "eventmesh")); + Assertions.assertThrows(ExtensionException.class, () -> EventMeshExtensionFactory.getExtension(TestPrototypeExtension.class, null)); } } diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/AnotherSingletonExtension.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/AnotherSingletonExtension.java new file mode 100644 index 0000000000..d7de5985b6 --- /dev/null +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/AnotherSingletonExtension.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.spi.example; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class AnotherSingletonExtension implements TestAnotherSingletonExtension { + + @Override + public void hello() { + log.info("I am SingletonExtension"); + } +} 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 index aa3223ffbe..6684c72510 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.spi.example; - import lombok.extern.slf4j.Slf4j; @Slf4j 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 index ee4e056faa..3c398f4dc8 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.spi.example; - import lombok.extern.slf4j.Slf4j; @Slf4j diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestAnotherSingletonExtension.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestAnotherSingletonExtension.java new file mode 100644 index 0000000000..92d7b1fd33 --- /dev/null +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestAnotherSingletonExtension.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; + +/** + * TestAnotherSingletonExtension + */ +@EventMeshSPI(eventMeshExtensionType = EventMeshExtensionType.SECURITY) +public interface TestAnotherSingletonExtension { + + void hello(); +} diff --git a/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestAnotherSingletonExtension b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestAnotherSingletonExtension new file mode 100644 index 0000000000..c8db961c38 --- /dev/null +++ b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestAnotherSingletonExtension @@ -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.AnotherSingletonExtension diff --git a/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/AsyncConsumeContext.java b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/AsyncConsumeContext.java index 7c1c739cd5..d56ef58fba 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/AsyncConsumeContext.java +++ b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/AsyncConsumeContext.java @@ -17,7 +17,6 @@ package org.apache.eventmesh.api; - public abstract class AsyncConsumeContext { public abstract void commit(EventMeshAction action); diff --git a/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/EventListener.java b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/EventListener.java index 12e9b8755d..4416b1ea58 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/EventListener.java +++ b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/EventListener.java @@ -17,7 +17,6 @@ package org.apache.eventmesh.api; - import io.cloudevents.CloudEvent; /** diff --git a/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/TopicNameHelper.java b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/TopicNameHelper.java new file mode 100644 index 0000000000..8a7d34f320 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/TopicNameHelper.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; + +import org.apache.eventmesh.spi.EventMeshExtensionType; +import org.apache.eventmesh.spi.EventMeshSPI; + +import lombok.SneakyThrows; + +/** + * Topic name generator. + */ +@EventMeshSPI(isSingleton = false, eventMeshExtensionType = EventMeshExtensionType.STORAGE) +public interface TopicNameHelper { + + @SneakyThrows + default boolean isRetryTopic(String retryTopic) { + throw new IllegalAccessException("Method not supported."); + } +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/admin/AbstractAdmin.java b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/admin/AbstractAdmin.java new file mode 100644 index 0000000000..5668dbb178 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/admin/AbstractAdmin.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.api.admin; + +import java.util.List; +import java.util.Properties; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.cloudevents.CloudEvent; + +public abstract class AbstractAdmin implements Admin { + + private final AtomicBoolean started; + + public AbstractAdmin(AtomicBoolean started) { + this.started = started; + } + + @Override + public boolean isStarted() { + return started.get(); + } + + @Override + public boolean isClosed() { + return !started.get(); + } + + @Override + public void start() { + started.set(true); + } + + @Override + public void shutdown() { + started.set(false); + } + + @Override + public void init(Properties properties) throws Exception { + + } + + @Override + public List getEvent(String topicName, int offset, int length) throws Exception { + return null; + } + + @Override + public void publish(CloudEvent cloudEvent) throws Exception { + } +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/admin/TopicProperties.java b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/admin/TopicProperties.java index e138aaf807..775e998ba2 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/admin/TopicProperties.java +++ b/eventmesh-storage-plugin/eventmesh-storage-api/src/main/java/org/apache/eventmesh/api/admin/TopicProperties.java @@ -28,8 +28,7 @@ public class TopicProperties { @JsonCreator public TopicProperties( @JsonProperty("name") String name, - @JsonProperty("messageCount") long messageCount - ) { + @JsonProperty("messageCount") long messageCount) { super(); this.name = name; this.messageCount = messageCount; diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/build.gradle b/eventmesh-storage-plugin/eventmesh-storage-kafka/build.gradle index 10f1cdf2e4..d776cc46a7 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-kafka/build.gradle +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/build.gradle @@ -23,20 +23,17 @@ dependencies { implementation project(":eventmesh-storage-plugin:eventmesh-storage-api") implementation project(":eventmesh-common") // https://mavenlibs.com/maven/dependency/io.cloudevents/cloudevents-kafka - implementation group: 'io.cloudevents', name: 'cloudevents-kafka', version: '2.2.1' + implementation group: 'io.cloudevents', name: 'cloudevents-kafka', version: '2.4.2' // https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients implementation 'org.apache.kafka:kafka-clients:3.0.0' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + testImplementation 'org.junit.jupiter:junit-jupiter:5.6.0' testImplementation project(":eventmesh-storage-plugin:eventmesh-storage-api") testImplementation project(":eventmesh-common") testImplementation "org.mockito:mockito-core" - testImplementation "org.powermock:powermock-module-junit4" - testImplementation "org.powermock:powermock-api-mockito2" compileOnly 'org.projectlombok:lombok' compileOnly 'com.google.code.findbugs:jsr305:3.0.2' diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/admin/KafkaAdmin.java b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/admin/KafkaAdmin.java new file mode 100644 index 0000000000..f86bfee87d --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/admin/KafkaAdmin.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.storage.kafka.admin; + +import static org.apache.eventmesh.storage.kafka.common.EventMeshConstants.DEFAULT_TIMEOUT_IN_SECONDS; + +import org.apache.eventmesh.api.admin.AbstractAdmin; +import org.apache.eventmesh.api.admin.TopicProperties; +import org.apache.eventmesh.common.config.ConfigService; +import org.apache.eventmesh.storage.kafka.config.ClientConfiguration; + +import org.apache.kafka.clients.admin.Admin; +import org.apache.kafka.clients.admin.ListOffsetsResult.ListOffsetsResultInfo; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.admin.OffsetSpec; +import org.apache.kafka.clients.admin.TopicDescription; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.common.KafkaFuture; +import org.apache.kafka.common.TopicPartition; +import org.apache.kafka.common.TopicPartitionInfo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class KafkaAdmin extends AbstractAdmin { + + // properties for kafka admin client + private static final Properties kafkaProps = new Properties(); + + // properties for topic management + private static final Map topicProps = new HashMap<>(); + + public KafkaAdmin() { + super(new AtomicBoolean(false)); + + ConfigService configService = ConfigService.getInstance(); + ClientConfiguration clientConfiguration = configService.buildConfigInstance(ClientConfiguration.class); + + kafkaProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, clientConfiguration.getNamesrvAddr()); + topicProps.put("partitionNum", clientConfiguration.getPartitions()); + topicProps.put("replicationFactorNum", (int) clientConfiguration.getReplicationFactors()); + } + + @Override + public List getTopic() { + try (Admin client = Admin.create(kafkaProps)) { + Set topicList = client.listTopics().names().get(DEFAULT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); + Map> topicDescriptionFutures = client.describeTopics(topicList).values(); + List result = new ArrayList<>(); + for (Entry> entry : topicDescriptionFutures.entrySet()) { + String topicName = entry.getKey(); + TopicDescription topicDescription = entry.getValue().get(DEFAULT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); + + long messageCount = topicDescription.partitions().stream() + .mapToInt(TopicPartitionInfo::partition) + .mapToLong(partition -> { + try { + return getMsgCount(topicName, partition, client); + } catch (TimeoutException e) { + log.error("Failed to get msg offset when listing topics. Kafka response timed out in {} seconds.", + DEFAULT_TIMEOUT_IN_SECONDS); + throw new RuntimeException(e); + } catch (ExecutionException | InterruptedException e) { + log.error("Failed to get msg offset when listing topics.", e); + throw new RuntimeException(e); + } + }) + .sum(); + + result.add(new TopicProperties(topicName, messageCount)); + } + result.sort(Comparator.comparing(t -> t.name)); + return result; + } catch (TimeoutException e) { + log.error("Failed to list topics. Kafka response timed out in {} seconds.", DEFAULT_TIMEOUT_IN_SECONDS); + throw new RuntimeException(e); + } catch (Exception e) { + log.error("Failed to list topics.", e); + throw new RuntimeException(e); + } + } + + private long getMsgCount(String topicName, int partition, Admin client) throws ExecutionException, InterruptedException, TimeoutException { + TopicPartition topicPartition = new TopicPartition(topicName, partition); + long earliestOffset = getOffset(topicPartition, OffsetSpec.earliest(), client); + long latestOffset = getOffset(topicPartition, OffsetSpec.latest(), client); + return latestOffset - earliestOffset; + } + + private long getOffset(TopicPartition topicPartition, OffsetSpec offsetSpec, Admin client) + throws ExecutionException, InterruptedException, TimeoutException { + Map offsetSpecMap = Collections.singletonMap(topicPartition, offsetSpec); + Map offsetResultMap = + client.listOffsets(offsetSpecMap).all().get(DEFAULT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); + return offsetResultMap.get(topicPartition).offset(); + } + + @Override + public void createTopic(String topicName) { + try (Admin client = Admin.create(kafkaProps)) { + NewTopic newTopic = new NewTopic(topicName, topicProps.get("partitionNum"), topicProps.get("replicationFactorNum").shortValue()); + client.createTopics(Collections.singletonList(newTopic)).all().get(DEFAULT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); + } catch (TimeoutException e) { + log.error("Failed to create topic. Kafka response timed out in {} seconds.", DEFAULT_TIMEOUT_IN_SECONDS); + } catch (Exception e) { + log.error("Failed to create topic.", e); + } + } + + @Override + public void deleteTopic(String topicName) { + try (Admin client = Admin.create(kafkaProps)) { + client.deleteTopics(Collections.singletonList(topicName)).all().get(DEFAULT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); + } catch (TimeoutException e) { + log.error("Failed to delete topic. Kafka response timed out in {} seconds.", DEFAULT_TIMEOUT_IN_SECONDS); + } catch (Exception e) { + log.error("Failed to delete topic.", e); + } + } + +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/admin/KafkaAdminAdaptor.java b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/admin/KafkaAdminAdaptor.java new file mode 100644 index 0000000000..042756d457 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/admin/KafkaAdminAdaptor.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.storage.kafka.admin; + +import org.apache.eventmesh.api.admin.Admin; +import org.apache.eventmesh.api.admin.TopicProperties; + +import java.util.List; +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +public class KafkaAdminAdaptor implements Admin { + + private final KafkaAdmin admin; + + public KafkaAdminAdaptor() { + admin = new KafkaAdmin(); + } + + @Override + public boolean isStarted() { + return admin.isStarted(); + } + + @Override + public boolean isClosed() { + return admin.isClosed(); + } + + @Override + public void start() { + admin.start(); + } + + @Override + public void shutdown() { + admin.shutdown(); + } + + @Override + public void init(Properties properties) throws Exception { + admin.init(properties); + } + + @Override + public List getTopic() throws Exception { + return admin.getTopic(); + } + + @Override + public void createTopic(String topicName) throws Exception { + admin.createTopic(topicName); + } + + @Override + public void deleteTopic(String topicName) throws Exception { + admin.deleteTopic(topicName); + } + + @Override + public List getEvent(String topicName, int offset, int length) throws Exception { + return admin.getEvent(topicName, offset, length); + } + + @Override + public void publish(CloudEvent cloudEvent) throws Exception { + admin.publish(cloudEvent); + } +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/common/EventMeshConstants.java b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/common/EventMeshConstants.java index 2bc2f3c04a..4b54846ce4 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/common/EventMeshConstants.java +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/common/EventMeshConstants.java @@ -23,5 +23,7 @@ public class EventMeshConstants { public static final int DEFAULT_TIMEOUT_IN_MILLISECONDS = 3000; + public static final int DEFAULT_TIMEOUT_IN_SECONDS = 10; + public static final String STORE_TIMESTAMP = "storetime"; } diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/config/ClientConfiguration.java b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/config/ClientConfiguration.java index 3749e81578..2e92877ec0 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/config/ClientConfiguration.java +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/config/ClientConfiguration.java @@ -44,6 +44,14 @@ public class ClientConfiguration { @Builder.Default private String clientPass = "password"; + @ConfigFiled(field = "num.partitions") + @Builder.Default + private int partitions = 1; + + @ConfigFiled(field = "num.replicationFactors") + @Builder.Default + private short replicationFactors = 1; + @ConfigFiled(field = "client.consumeThreadMin") @Builder.Default private Integer consumeThreadMin = 2; diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/consumer/ConsumerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/consumer/ConsumerImpl.java index 795b9089be..467ffb7d0f 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/consumer/ConsumerImpl.java +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/consumer/ConsumerImpl.java @@ -38,7 +38,6 @@ import io.cloudevents.CloudEvent; import io.cloudevents.kafka.CloudEventDeserializer; - import lombok.extern.slf4j.Slf4j; @Slf4j @@ -83,7 +82,6 @@ public void start() { } } - public synchronized void shutdown() { if (this.started.compareAndSet(true, false)) { // Shutdown the executor and interrupt any running tasks @@ -92,12 +90,10 @@ public synchronized void shutdown() { } } - public boolean isStarted() { return this.started.get(); } - public boolean isClosed() { return !this.isStarted(); } diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/consumer/KafkaConsumerRunner.java b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/consumer/KafkaConsumerRunner.java index 69ec904bbb..93d86181a5 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/consumer/KafkaConsumerRunner.java +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/java/org/apache/eventmesh/storage/kafka/consumer/KafkaConsumerRunner.java @@ -69,6 +69,7 @@ public void run() { CloudEvent cloudEvent = rec.value(); String topicName = cloudEvent.getSubject(); EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = new EventMeshAsyncConsumeContext() { + @Override public void commit(EventMeshAction action) { switch (action) { diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin new file mode 100644 index 0000000000..9f8cb52ae3 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin @@ -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. + +kafka=org.apache.eventmesh.storage.kafka.admin.KafkaAdminAdaptor \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/resources/kafka-client.properties b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/resources/kafka-client.properties index 31923d73d6..cbe0a036fa 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/resources/kafka-client.properties +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/main/resources/kafka-client.properties @@ -14,13 +14,23 @@ # See the License for the specific language governing permissions and # limitations under the License. # -#######################kafka-client################## -eventMesh.server.kafka.namesrvAddr=127.0.0.1:9092;127.0.0.1:9092 + +# Configurations started with 'eventMesh.server.kafka' are required for EventMesh. +# You may see kafka.server.KafkaConfig for additional details and defaults of the rest of the configurations. + +############################# EventMesh Kafka Client ############################# + +eventMesh.server.kafka.namesrvAddr=localhost:9092;localhost:9092 eventMesh.server.kafka.cluster=DefaultCluster eventMesh.server.kafka.accessKey=******** eventMesh.server.kafka.secretKey=******** -# see kafka.server.KafkaConfig for additional details and defaults +############################# EventMesh Log Basics ############################# + +# the number of partitions per topic +eventMesh.server.kafka.num.partitions=1 +# the number of replication factors per topic +eventMesh.server.kafka.num.replicationFactors=1 ############################# Server Basics ############################# @@ -29,10 +39,6 @@ broker.id=0 ############################# Socket Server Settings ############################# -# The port the socket server listens on -eventMesh.server.kafka.port=9092 -eventMesh.server.kafka.bootstrap.servers=localhost:9092 - # Hostname the broker will bind to. If not set, the server will bind to all interfaces #host.name=localhost diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/test/java/org/apache/eventmesh/storage/kafka/config/ClientConfigurationTest.java b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/test/java/org/apache/eventmesh/storage/kafka/config/ClientConfigurationTest.java index b2de564935..d9a0c8ca0f 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/test/java/org/apache/eventmesh/storage/kafka/config/ClientConfigurationTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/test/java/org/apache/eventmesh/storage/kafka/config/ClientConfigurationTest.java @@ -21,8 +21,8 @@ import org.apache.eventmesh.storage.kafka.consumer.KafkaConsumerImpl; import org.apache.eventmesh.storage.kafka.producer.KafkaProducerImpl; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; /** * test config of Kafka SPI Impl @@ -50,22 +50,22 @@ public void getConfigWhenKafkaProducerImplInit() { } private void assertConfig(ClientConfiguration config) { - Assert.assertEquals("127.0.0.1:9092;127.0.0.1:9092", config.getNamesrvAddr()); - Assert.assertEquals("username-succeed!!!", config.getClientUserName()); - Assert.assertEquals("password-succeed!!!", config.getClientPass()); - Assert.assertEquals(Integer.valueOf(1816), config.getConsumeThreadMin()); - Assert.assertEquals(Integer.valueOf(2816), config.getConsumeThreadMax()); - Assert.assertEquals(Integer.valueOf(3816), config.getConsumeQueueSize()); - Assert.assertEquals(Integer.valueOf(4816), config.getPullBatchSize()); - Assert.assertEquals(Integer.valueOf(5816), config.getAckWindow()); - Assert.assertEquals(Integer.valueOf(6816), config.getPubWindow()); - Assert.assertEquals(7816, config.getConsumeTimeout()); - Assert.assertEquals(Integer.valueOf(8816), config.getPollNameServerInterval()); - Assert.assertEquals(Integer.valueOf(9816), config.getHeartbeatBrokerInterval()); - Assert.assertEquals(Integer.valueOf(11816), config.getRebalanceInterval()); - Assert.assertEquals("cluster-succeed!!!", config.getClusterName()); - Assert.assertEquals("accessKey-succeed!!!", config.getAccessKey()); - Assert.assertEquals("secretKey-succeed!!!", config.getSecretKey()); + Assertions.assertEquals("127.0.0.1:9092;127.0.0.1:9092", config.getNamesrvAddr()); + Assertions.assertEquals("username-succeed!!!", config.getClientUserName()); + Assertions.assertEquals("password-succeed!!!", config.getClientPass()); + Assertions.assertEquals(Integer.valueOf(1816), config.getConsumeThreadMin()); + Assertions.assertEquals(Integer.valueOf(2816), config.getConsumeThreadMax()); + Assertions.assertEquals(Integer.valueOf(3816), config.getConsumeQueueSize()); + Assertions.assertEquals(Integer.valueOf(4816), config.getPullBatchSize()); + Assertions.assertEquals(Integer.valueOf(5816), config.getAckWindow()); + Assertions.assertEquals(Integer.valueOf(6816), config.getPubWindow()); + Assertions.assertEquals(7816, config.getConsumeTimeout()); + Assertions.assertEquals(Integer.valueOf(8816), config.getPollNameServerInterval()); + Assertions.assertEquals(Integer.valueOf(9816), config.getHeartbeatBrokerInterval()); + Assertions.assertEquals(Integer.valueOf(11816), config.getRebalanceInterval()); + Assertions.assertEquals("cluster-succeed!!!", config.getClusterName()); + Assertions.assertEquals("accessKey-succeed!!!", config.getAccessKey()); + Assertions.assertEquals("secretKey-succeed!!!", config.getSecretKey()); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/test/resources/kafka-client.properties b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/test/resources/kafka-client.properties index 3b0c217e0a..d8517aad16 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-kafka/src/test/resources/kafka-client.properties +++ b/eventmesh-storage-plugin/eventmesh-storage-kafka/src/test/resources/kafka-client.properties @@ -30,19 +30,4 @@ eventMesh.server.kafka.client.heartbeatBrokerInterval=9816 eventMesh.server.kafka.client.rebalanceInterval=11816 eventMesh.server.kafka.cluster=cluster-succeed!!! eventMesh.server.kafka.accessKey=accessKey-succeed!!! -eventMesh.server.kafka.secretKey=secretKey-succeed!!! -eventMesh.server.kafka.username=username-succeed!!! -eventMesh.server.kafka.password=password-succeed!!! -eventMesh.server.kafka.client.consumeThreadMin=1816 -eventMesh.server.kafka.client.consumeThreadMax=2816 -eventMesh.server.kafka.client.consumeThreadPoolQueueSize=3816 -eventMesh.server.kafka.client.pullBatchSize=4816 -eventMesh.server.kafka.client.ackwindow=5816 -eventMesh.server.kafka.client.pubwindow=6816 -eventMesh.server.kafka.client.comsumeTimeoutInMin=7816 -eventMesh.server.kafka.client.pollNameServerInterval=8816 -eventMesh.server.kafka.client.heartbeatBrokerInterval=9816 -eventMesh.server.kafka.client.rebalanceInterval=11816 -eventMesh.server.kafka.cluster=cluster-succeed!!! -eventMesh.server.kafka.accessKey=accessKey-succeed!!! eventMesh.server.kafka.secretKey=secretKey-succeed!!! \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/build.gradle b/eventmesh-storage-plugin/eventmesh-storage-knative/build.gradle deleted file mode 100644 index ae6a36f5dc..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/build.gradle +++ /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. - */ - -dependencies { - implementation 'org.asynchttpclient:async-http-client' - - implementation project(":eventmesh-sdks:eventmesh-sdk-java") - testImplementation project(":eventmesh-sdks:eventmesh-sdk-java") - - implementation project(":eventmesh-runtime") - testImplementation project(":eventmesh-runtime") - - implementation project(":eventmesh-common") - testImplementation project(":eventmesh-common") - - implementation project(":eventmesh-storage-plugin:eventmesh-storage-api") - testImplementation project(":eventmesh-storage-plugin:eventmesh-storage-api") - - testImplementation "org.powermock:powermock-module-junit4" - - 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-storage-plugin/eventmesh-storage-knative/gradle.properties b/eventmesh-storage-plugin/eventmesh-storage-knative/gradle.properties deleted file mode 100644 index 8ba4f21ce0..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/gradle.properties +++ /dev/null @@ -1,18 +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. -# -knative_version=1.5 -pluginType=storage -pluginName=knative \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeBinaryMessageReader.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeBinaryMessageReader.java deleted file mode 100644 index 8a3060cabc..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeBinaryMessageReader.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.cloudevent.impl; - -import java.util.Locale; -import java.util.function.BiConsumer; - -import io.cloudevents.SpecVersion; -import io.cloudevents.core.data.BytesCloudEventData; -import io.cloudevents.core.message.impl.BaseGenericBinaryMessageReaderImpl; - -public class KnativeBinaryMessageReader extends BaseGenericBinaryMessageReaderImpl { - - protected KnativeBinaryMessageReader(SpecVersion version, byte[] body) { - super(version, body != null && body.length > 0 ? BytesCloudEventData.wrap(body) : (BytesCloudEventData) null); - } - - @Override - protected boolean isContentTypeHeader(String key) { - return KnativeHeaders.CONTENT_TYPE.equals(key); - } - - @Override - protected boolean isCloudEventsHeader(String key) { - return true; - } - - @Override - protected String toCloudEventsKey(String key) { - return key.toLowerCase(Locale.getDefault()); - } - - @Override - protected void forEachHeader(BiConsumer fn) { - - } - - @Override - protected String toCloudEventsValue(String value) { - return value; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeMessageWriter.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeMessageWriter.java deleted file mode 100644 index 273ee30d63..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/cloudevent/impl/KnativeMessageWriter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.cloudevent.impl; - -import org.apache.commons.lang3.ObjectUtils; - -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.Properties; - -import javax.annotation.Nullable; - -import io.cloudevents.CloudEvent; -import io.cloudevents.CloudEventData; -import io.cloudevents.SpecVersion; -import io.cloudevents.core.format.EventFormat; -import io.cloudevents.core.message.MessageWriter; -import io.cloudevents.core.v1.CloudEventBuilder; -import io.cloudevents.rw.CloudEventContextWriter; -import io.cloudevents.rw.CloudEventRWException; -import io.cloudevents.rw.CloudEventWriter; - -public class KnativeMessageWriter implements MessageWriter, String>, CloudEventWriter { - - private transient CloudEvent message; - - public CloudEvent getMessage() { - return this.message; - } - - public KnativeMessageWriter(Properties properties) { - String s = "{ \"msg\": [\"" + properties.get("data") + "\"]}"; - this.message = new CloudEventBuilder() - .withId(properties.getProperty(KnativeHeaders.CE_ID)) - .withSource(URI.create(properties.getProperty(KnativeHeaders.CE_SOURCE))) - .withType(properties.getProperty(KnativeHeaders.CE_TYPE)) - .withDataContentType(properties.getProperty(KnativeHeaders.CONTENT_TYPE)) - .withData(s.getBytes(StandardCharsets.UTF_8)) - .build(); - } - - @Override - public String end(CloudEventData data) throws CloudEventRWException { - return data.toString(); - } - - @Override - public String end() throws CloudEventRWException { - if (ObjectUtils.allNotNull(message, message.getData())) { - return message.getData().toString(); - } - throw CloudEventRWException.newOther(new IllegalArgumentException("message data is null")); - } - - @Override - public CloudEventContextWriter withContextAttribute(@Nullable String name, @Nullable String value) throws CloudEventRWException { - return null; - } - - @Override - public String setEvent(@Nullable EventFormat format, @Nullable byte[] value) throws CloudEventRWException { - return null; - } - - @Override - public CloudEventWriter create(SpecVersion version) throws CloudEventRWException { - return null; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/config/ClientConfiguration.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/config/ClientConfiguration.java deleted file mode 100644 index 5c06304703..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/config/ClientConfiguration.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 org.apache.eventmesh.storage.knative.config; - -import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.common.config.ConfigFiled; -import org.apache.eventmesh.common.config.convert.converter.ListConverter.ListConverterSemi; - -import java.util.List; - -import lombok.Data; - -@Data -@Config(prefix = "eventMesh.server.knative", path = "classPath://knative-client.properties") -public class ClientConfiguration { - - @ConfigFiled(field = "service", converter = ListConverterSemi.class) - public List service; - - /** - * In keeping with the old way of configuration parsing, the value is taken from the service field [0] - */ - @ConfigFiled(reload = true) - public String emurl = ""; - - /** - * In keeping with the old way of configuration parsing, the value is taken from the service field [1] - */ - @ConfigFiled(reload = true) - public String serviceAddr = ""; - - public void reload() { - emurl = this.service.get(0); - serviceAddr = this.service.get(1); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/DefaultConsumer.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/DefaultConsumer.java deleted file mode 100644 index 2130ed8529..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/DefaultConsumer.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 org.apache.eventmesh.storage.knative.consumer; - -import static org.asynchttpclient.Dsl.asyncHttpClient; - -import org.apache.eventmesh.storage.knative.patch.EventMeshMessageListenerConcurrently; - -import java.util.concurrent.TimeUnit; - -import org.asynchttpclient.AsyncHttpClient; -import org.asynchttpclient.ListenableFuture; -import org.asynchttpclient.Response; -import org.asynchttpclient.util.HttpConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Preconditions; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class DefaultConsumer { - - private static final Logger LOG = LoggerFactory.getLogger(DefaultConsumer.class); - - private transient AsyncHttpClient asyncHttpClient; - - - private transient EventMeshMessageListenerConcurrently messageListener; - - public EventMeshMessageListenerConcurrently getMessageListener() { - return messageListener; - } - - public DefaultConsumer() throws Exception { - this.asyncHttpClient = asyncHttpClient(); - } - - public String pullMessage(String topic, String subscribeUrl) throws Exception { - Preconditions.checkNotNull(topic, "Subscribe item cannot be null"); - Preconditions.checkNotNull(subscribeUrl, "SubscribeUrl cannot be null"); - - // Get event message via HTTP: - String responseBody; - ListenableFuture execute = asyncHttpClient.prepareGet("http://" + subscribeUrl + "/" + topic).execute(); - Response response = execute.get(10, TimeUnit.SECONDS); - - if (response.getStatusCode() == HttpConstants.ResponseStatusCodes.OK_200) { - responseBody = response.getResponseBody(); - LOG.info(responseBody); - return responseBody; - } - throw new IllegalStateException("HTTP response code error: " + response.getStatusCode()); - } - - public void registerMessageListener(EventMeshMessageListenerConcurrently messageListener) { - this.messageListener = messageListener; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImpl.java deleted file mode 100644 index fa71710315..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.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.config.Config; -import org.apache.eventmesh.storage.knative.config.ClientConfiguration; - -import java.util.List; -import java.util.Properties; - -import io.cloudevents.CloudEvent; - -import lombok.extern.slf4j.Slf4j; - -@Config(field = "clientConfiguration") -@Slf4j -public class KnativeConsumerImpl implements Consumer { - - private transient PullConsumerImpl pullConsumer; - - /** - * Unified configuration class corresponding to knative-client.properties - */ - private ClientConfiguration clientConfiguration; - - @Override - public synchronized void init(Properties properties) throws Exception { - // Load parameters from properties file: - properties.put("emUrl", clientConfiguration.getEmurl()); - properties.put("serviceAddr", clientConfiguration.getServiceAddr()); - - pullConsumer = new PullConsumerImpl(properties); - } - - @Override - public void subscribe(String topic) { - pullConsumer.subscribe(topic); - } - - @Override - public void unsubscribe(String topic) { - try { - pullConsumer.unsubscribe(topic); - } catch (Exception e) { - log.error("unsubscribe error", e); - } - } - - @Override - public void registerEventListener(EventListener listener) { - pullConsumer.registerEventListener(listener); - } - - @Override - public void updateOffset(List cloudEvents, AbstractContext context) { - pullConsumer.updateOffset(cloudEvents, context); - } - - @Override - public boolean isStarted() { - return pullConsumer.isStarted(); - } - - @Override - public boolean isClosed() { - return pullConsumer.isClosed(); - } - - @Override - public void start() { - pullConsumer.start(); - } - - @Override - public void shutdown() { - pullConsumer.shutdown(); - } - - public ClientConfiguration getClientConfiguration() { - return this.clientConfiguration; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/PullConsumerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/PullConsumerImpl.java deleted file mode 100644 index c3378d05fc..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/consumer/PullConsumerImpl.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.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.common.protocol.SubscriptionItem; -import org.apache.eventmesh.common.protocol.SubscriptionMode; -import org.apache.eventmesh.common.protocol.SubscriptionType; -import org.apache.eventmesh.storage.knative.domain.NonStandardKeys; -import org.apache.eventmesh.storage.knative.patch.EventMeshConsumeConcurrentlyContext; -import org.apache.eventmesh.storage.knative.patch.EventMeshConsumeConcurrentlyStatus; -import org.apache.eventmesh.storage.knative.patch.EventMeshMessageListenerConcurrently; - -import java.util.List; -import java.util.Properties; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.cloudevents.CloudEvent; - -import com.google.common.collect.Lists; - -public class PullConsumerImpl { - - private static final Logger LOG = LoggerFactory.getLogger(PullConsumerImpl.class); - - private final transient DefaultConsumer defaultConsumer; - - // Topics to subscribe: - private transient List topicList = null; - private final transient ConcurrentHashMap offsetMap; - private final transient AtomicBoolean started = new AtomicBoolean(false); - private final transient Properties properties; - - // Store received message: - private transient ConcurrentMap subscriptionInner; - private transient EventListener eventListener; - - - - public PullConsumerImpl(final Properties properties) throws Exception { - this.properties = properties; - this.topicList = Lists.newArrayList(); - this.subscriptionInner = new ConcurrentHashMap(); - this.offsetMap = new ConcurrentHashMap<>(); - defaultConsumer = new DefaultConsumer(); - - // Register listener: - defaultConsumer.registerMessageListener(new ClusteringMessageListener()); - } - - public void subscribe(String topic) { - // Subscribe topics: - try { - // Add topic to topicList: - topicList.add(new SubscriptionItem(topic, SubscriptionMode.CLUSTERING, SubscriptionType.ASYNC)); - // Pull event messages iteratively: - topicList.forEach( - item -> { - try { - subscriptionInner.put(item.getTopic(), - defaultConsumer.pullMessage(item.getTopic(), properties.getProperty("serviceAddr"))); - } catch (Exception e) { - LOG.error("store received message error", e); - } - } - ); - } catch (Exception e) { - LOG.error("other error", e); - } - } - - public void unsubscribe(String topic) { - try { - // Unsubscribe topic: - topicList.remove(topic); - } catch (Exception e) { - LOG.error("unsubscribe topic error", e); - } - } - - // todo: offset - public void updateOffset(List cloudEvents, AbstractContext context) { - cloudEvents.forEach(cloudEvent -> this.updateOffset( - cloudEvent.getSubject(), (Long) cloudEvent.getExtension("offset")) - ); - } - - public void updateOffset(String topicMetadata, Long offset) { - offsetMap.computeIfPresent(topicMetadata, (k, v) -> { - v.set(offset); - return v; - }); - } - - public void start() { - this.started.set(true); - } - - public synchronized void shutdown() { - this.started.set(false); - } - - public boolean isStarted() { - return this.started.get(); - } - - public boolean isClosed() { - return !this.isStarted(); - } - - public void registerEventListener(EventListener listener) { - this.eventListener = listener; - } - - // todo: load balancer cluser and broadcast - private class ClusteringMessageListener extends EventMeshMessageListenerConcurrently { - @Override - public EventMeshConsumeConcurrentlyStatus handleMessage(CloudEvent cloudEvent, EventMeshConsumeConcurrentlyContext context) { - 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((AbstractContext) context); - - // Consume received message: - eventListener.consume(cloudEvent, eventMeshAsyncConsumeContext); - - return EventMeshConsumeConcurrentlyStatus.valueOf( - contextProperties.getProperty(NonStandardKeys.MESSAGE_CONSUME_STATUS)); - } - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/domain/NonStandardKeys.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/domain/NonStandardKeys.java deleted file mode 100644 index 7c829afb2f..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/domain/NonStandardKeys.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 org.apache.eventmesh.storage.knative.domain; - -/** - * NonStandardKeys - */ -public class NonStandardKeys { - - public static final String MESSAGE_CONSUME_STATUS = "em.message.consume.status"; - -} \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyContext.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyContext.java deleted file mode 100644 index 0c0fb9b12b..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyContext.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.patch; - -public class EventMeshConsumeConcurrentlyContext { - private boolean manualAck = true; - - public boolean isManualAck() { - return manualAck; - } - - public void setManualAck(boolean manualAck) { - this.manualAck = manualAck; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyStatus.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyStatus.java deleted file mode 100644 index 3a2e2f30e9..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshConsumeConcurrentlyStatus.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.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-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshMessageListenerConcurrently.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshMessageListenerConcurrently.java deleted file mode 100644 index 6a0512fe3e..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/patch/EventMeshMessageListenerConcurrently.java +++ /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. - */ - -package org.apache.eventmesh.storage.knative.patch; - -import io.cloudevents.CloudEvent; - -public abstract class EventMeshMessageListenerConcurrently { - public abstract EventMeshConsumeConcurrentlyStatus handleMessage(CloudEvent cloudEvent, EventMeshConsumeConcurrentlyContext context); -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/AbstractProducer.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/AbstractProducer.java deleted file mode 100644 index 0ef390dcfa..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/AbstractProducer.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.producer; - -import static org.asynchttpclient.Dsl.asyncHttpClient; - -import org.apache.eventmesh.api.exception.StorageRuntimeException; -import org.apache.eventmesh.api.producer.Producer; - -import java.util.Properties; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.asynchttpclient.AsyncHttpClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.cloudevents.CloudEvent; - -public abstract class AbstractProducer implements Producer { - - protected static final Logger LOG = LoggerFactory.getLogger(AbstractProducer.class); - - protected final transient AtomicBoolean started = new AtomicBoolean(false); - protected final transient Properties properties; - private transient AsyncHttpClient asyncHttpClient; - - AbstractProducer(final Properties properties) { - this.properties = properties; - this.asyncHttpClient = asyncHttpClient(); - } - - StorageRuntimeException checkProducerException(CloudEvent cloudEvent, Throwable e) { - if (cloudEvent.getData() == null) { - return new StorageRuntimeException(String.format("CloudEvent message data does not exist.", e)); - } - return new StorageRuntimeException(String.format("Unknown connector runtime exception.", e)); - } - - @Override - public boolean isStarted() { - return started.get(); - } - - @Override - public boolean isClosed() { - return !this.isStarted(); - } - - public AsyncHttpClient getAsyncHttpClient() { - return asyncHttpClient; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImpl.java deleted file mode 100644 index 7817436e2a..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImpl.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.producer; - -import org.apache.eventmesh.api.RequestReplyCallback; -import org.apache.eventmesh.api.SendCallback; -import org.apache.eventmesh.api.exception.StorageRuntimeException; -import org.apache.eventmesh.api.producer.Producer; -import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.storage.knative.config.ClientConfiguration; - -import java.util.Properties; - -import io.cloudevents.CloudEvent; - -@Config(field = "clientConfiguration") -public class KnativeProducerImpl implements Producer { - - private transient ProducerImpl producer; - - /** - * Unified configuration class corresponding to knative-client.properties - */ - private ClientConfiguration clientConfiguration; - - @Override - public synchronized void init(Properties properties) throws Exception { - // Load parameters from properties file: - properties.put("url", clientConfiguration.getServiceAddr()); - producer = new ProducerImpl(properties); - } - - @Override - public void publish(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { - producer.sendAsync(cloudEvent, sendCallback); - } - - @Override - public boolean isStarted() { - return producer.isStarted(); - } - - @Override - public boolean isClosed() { - return producer.isClosed(); - } - - @Override - public void start() { - throw new StorageRuntimeException("Start is not supported"); - } - - @Override - public void shutdown() { - throw new StorageRuntimeException("Shutdown is not supported"); - } - - @Override - public void sendOneway(CloudEvent cloudEvent) { - throw new StorageRuntimeException("SendOneWay is not supported"); - } - - @Override - public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) throws Exception { - throw new StorageRuntimeException("Request is not supported"); - } - - @Override - public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { - throw new StorageRuntimeException("Reply is not supported"); - } - - @Override - public void checkTopicExist(String topic) throws Exception { - throw new StorageRuntimeException("CheckTopicExist is not supported"); - } - - @Override - public void setExtFields() { - throw new StorageRuntimeException("SetExtFields is not supported"); - } - - public ClientConfiguration getClientConfiguration() { - return this.clientConfiguration; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/ProducerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/ProducerImpl.java deleted file mode 100644 index c360455556..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/producer/ProducerImpl.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.producer; - -import org.apache.eventmesh.api.RequestReplyCallback; -import org.apache.eventmesh.api.SendCallback; -import org.apache.eventmesh.api.exception.OnExceptionContext; -import org.apache.eventmesh.api.exception.StorageRuntimeException; -import org.apache.eventmesh.storage.knative.cloudevent.KnativeMessageFactory; -import org.apache.eventmesh.storage.knative.cloudevent.impl.KnativeHeaders; -import org.apache.eventmesh.storage.knative.utils.CloudEventUtils; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -import org.asynchttpclient.ListenableFuture; -import org.asynchttpclient.Response; -import org.asynchttpclient.util.HttpConstants; - -import io.cloudevents.CloudEvent; - -public class ProducerImpl extends AbstractProducer { - - public ProducerImpl(final Properties properties) throws IOException { - super(properties); - } - - public Properties attributes() { - return properties; - } - - public void send(CloudEvent cloudEvent, SendCallback sendCallback) { - // Set HTTP header, body and send CloudEvent message: - try { - ListenableFuture execute = super.getAsyncHttpClient().preparePost("http://" + this.attributes().getProperty("url")) - .addHeader(KnativeHeaders.CONTENT_TYPE, cloudEvent.getDataContentType()) - .addHeader(KnativeHeaders.CE_ID, cloudEvent.getId()) - .addHeader(KnativeHeaders.CE_SPECVERSION, String.valueOf(cloudEvent.getSpecVersion())) - .addHeader(KnativeHeaders.CE_TYPE, cloudEvent.getType()) - .addHeader(KnativeHeaders.CE_SOURCE, String.valueOf(cloudEvent.getSource())) - .setBody(KnativeMessageFactory.createReader(cloudEvent)) - .execute(); - - Response response = execute.get(10, TimeUnit.SECONDS); - if (response.getStatusCode() == HttpConstants.ResponseStatusCodes.OK_200) { - sendCallback.onSuccess(CloudEventUtils.convertSendResult(cloudEvent)); - return; - } - throw new IllegalStateException("HTTP response code error: " + response.getStatusCode()); - } catch (Exception e) { - StorageRuntimeException onsEx = ProducerImpl.this.checkProducerException(cloudEvent, e); - OnExceptionContext context = new OnExceptionContext(); - context.setTopic(KnativeMessageFactory.createReader(cloudEvent)); - context.setException(onsEx); - sendCallback.onException(context); - } - } - - public void sendAsync(CloudEvent cloudEvent, SendCallback sendCallback) { - try { - this.send(cloudEvent, sendCallback); - } catch (Exception e) { - //LOG.error("Send cloudevent message Exception", e); - throw new StorageRuntimeException("Send cloudevent message Exception.", e); - } - } - - @Override - public void init(Properties properties) throws Exception { - new ProducerImpl(properties); - } - - @Override - public void publish(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { - this.sendAsync(cloudEvent, sendCallback); - } - - @Override - public void sendOneway(CloudEvent cloudEvent) { - throw new StorageRuntimeException("SendOneWay is not supported"); - } - - @Override - public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) throws Exception { - throw new StorageRuntimeException("Request is not supported"); - } - - @Override - public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { - throw new StorageRuntimeException("Reply is not supported"); - } - - @Override - public void checkTopicExist(String topic) throws Exception { - throw new StorageRuntimeException("CheckTopicExist is not supported"); - } - - @Override - public void setExtFields() { - throw new StorageRuntimeException("SetExtFields is not supported"); - } - - @Override - public void start() { - started.set(true); - } - - @Override - public void shutdown() { - started.set(false); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/storage/StorageResourceServiceKnativeImpl.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/storage/StorageResourceServiceKnativeImpl.java deleted file mode 100644 index fabc3d3301..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/storage/StorageResourceServiceKnativeImpl.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 org.apache.eventmesh.storage.knative.storage; - -import org.apache.eventmesh.api.storage.StorageResourceService; - -public class StorageResourceServiceKnativeImpl implements StorageResourceService { - @Override - public void init() throws Exception { - - } - - @Override - public void release() throws Exception { - - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/utils/CloudEventUtils.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/utils/CloudEventUtils.java deleted file mode 100644 index 9b2b4c96a0..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/java/org/apache/eventmesh/storage/knative/utils/CloudEventUtils.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.utils; - -import org.apache.eventmesh.api.SendResult; -import org.apache.eventmesh.storage.knative.cloudevent.KnativeMessageFactory; - -import io.cloudevents.CloudEvent; - -public class CloudEventUtils { - - public static SendResult convertSendResult(CloudEvent cloudEvent) { - SendResult sendResult = new SendResult(); - sendResult.setTopic(KnativeMessageFactory.createReader(cloudEvent)); - sendResult.setMessageId(cloudEvent.getId()); - return sendResult; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer deleted file mode 100644 index 6b10baccef..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer +++ /dev/null @@ -1,16 +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. - -knative=org.apache.eventmesh.storage.knative.consumer.KnativeConsumerImpl \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer deleted file mode 100644 index bc5f8b41eb..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer +++ /dev/null @@ -1,16 +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. - -knative=org.apache.eventmesh.storage.knative.producer.KnativeProducerImpl \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService deleted file mode 100644 index 06c1075700..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService +++ /dev/null @@ -1,16 +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. - -knative=org.apache.eventmesh.storage.knative.storage.StorageResourceServiceKnativeImpl \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/knative-client.properties b/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/knative-client.properties deleted file mode 100644 index 8fec1c4302..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/main/resources/knative-client.properties +++ /dev/null @@ -1,18 +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. -# -#######################knative-client################## -eventMesh.server.knative.service=127.0.0.1;cloudevents-player.default.127.0.0.1.sslip.io diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/config/ClientConfigurationTest.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/config/ClientConfigurationTest.java deleted file mode 100644 index 9ff668a1c0..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/config/ClientConfigurationTest.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 org.apache.eventmesh.storage.knative.config; - -import org.apache.eventmesh.api.factory.StoragePluginFactory; -import org.apache.eventmesh.storage.knative.consumer.KnativeConsumerImpl; -import org.apache.eventmesh.storage.knative.producer.KnativeProducerImpl; - -import org.junit.Assert; -import org.junit.Test; - -public class ClientConfigurationTest { - - @Test - public void getConfigWhenKnativeConsumerInit() { - KnativeConsumerImpl consumer = - (KnativeConsumerImpl) StoragePluginFactory.getMeshMQPushConsumer("knative"); - - ClientConfiguration config = consumer.getClientConfiguration(); - assertConfig(config); - } - - @Test - public void getConfigWhenKnativeProducerInit() { - KnativeProducerImpl producer = - (KnativeProducerImpl) StoragePluginFactory.getMeshMQProducer("knative"); - - ClientConfiguration config = producer.getClientConfiguration(); - assertConfig(config); - } - - private void assertConfig(ClientConfiguration config) { - Assert.assertEquals(config.getEmurl(), "127.0.0.1"); - Assert.assertEquals(config.getServiceAddr(), "cloudevents-player.default.127.0.0.1.sslip.io"); - } -} \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImplTest.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImplTest.java deleted file mode 100644 index d2888ffb9b..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/consumer/KnativeConsumerImplTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.consumer; - -import org.apache.eventmesh.api.factory.StoragePluginFactory; - -import java.util.Properties; - -import org.junit.Assert; -import org.junit.Test; - -public class KnativeConsumerImplTest { - - @Test - public void testSubscribe() throws Exception { - Properties properties = new Properties(); - final String topic = "messages"; - properties.put("topic", topic); - - // Create a Knative consumer: - KnativeConsumerImpl knativeConsumer = - (KnativeConsumerImpl) StoragePluginFactory.getMeshMQPushConsumer("knative"); - - try { - knativeConsumer.init(properties); - - // Subscribe: - knativeConsumer.subscribe(properties.getProperty("topic")); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImplTest.java b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImplTest.java deleted file mode 100644 index 0ae77db30c..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/java/org/apache/eventmesh/storage/knative/producer/KnativeProducerImplTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.knative.producer; - -import org.apache.eventmesh.api.SendCallback; -import org.apache.eventmesh.api.SendResult; -import org.apache.eventmesh.api.exception.OnExceptionContext; -import org.apache.eventmesh.api.factory.StoragePluginFactory; -import org.apache.eventmesh.storage.knative.cloudevent.KnativeMessageFactory; -import org.apache.eventmesh.storage.knative.cloudevent.impl.KnativeHeaders; - -import java.util.Properties; - -import org.junit.Assert; -import org.junit.Test; - -public class KnativeProducerImplTest { - - @Test - public void testPublish() throws Exception { - Properties properties = new Properties(); - - properties.put(KnativeHeaders.CONTENT_TYPE, "application/json"); - properties.put(KnativeHeaders.CE_ID, "1234"); - properties.put(KnativeHeaders.CE_SPECVERSION, "1.0"); - properties.put(KnativeHeaders.CE_TYPE, "some-type"); - properties.put(KnativeHeaders.CE_SOURCE, "java-client"); - properties.put("data", "Hello Knative from EventMesh!"); - - // Create a Knative producer: - KnativeProducerImpl knativeProducer = - (KnativeProducerImpl) StoragePluginFactory.getMeshMQProducer("knative"); - - try { - knativeProducer.init(properties); - - // Publish an event message: - knativeProducer.publish(KnativeMessageFactory.createWriter(properties).getMessage(), new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - } - - @Override - public void onException(OnExceptionContext context) { - } - }); - } catch (Exception e) { - Assert.fail(e.getMessage()); - } - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/resources/knative-client.properties b/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/resources/knative-client.properties deleted file mode 100644 index 8fec1c4302..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-knative/src/test/resources/knative-client.properties +++ /dev/null @@ -1,18 +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. -# -#######################knative-client################## -eventMesh.server.knative.service=127.0.0.1;cloudevents-player.default.127.0.0.1.sslip.io diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/build.gradle b/eventmesh-storage-plugin/eventmesh-storage-mongodb/build.gradle deleted file mode 100644 index 5d4e671bd6..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/build.gradle +++ /dev/null @@ -1,47 +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. - */ - -configurations { - implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' - implementation.exclude group: 'log4j', module: 'log4j' -} - -dependencies { - implementation project(":eventmesh-storage-plugin:eventmesh-storage-api") - implementation project(":eventmesh-common") - - testImplementation project(":eventmesh-storage-plugin:eventmesh-storage-api") - testImplementation project(":eventmesh-common") - - implementation 'org.mongodb:mongodb-driver:3.12.11' - testImplementation 'org.mongodb:mongodb-driver:3.12.11' - - implementation 'io.cloudevents:cloudevents-json-jackson' - testImplementation 'io.cloudevents:cloudevents-json-jackson' - - testImplementation "org.mockito:mockito-core" - testImplementation "org.powermock:powermock-module-junit4" - testImplementation "org.powermock:powermock-api-mockito2" - - 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 'de.bwaldvogel:mongo-java-server:1.42.0' -} \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/gradle.properties b/eventmesh-storage-plugin/eventmesh-storage-mongodb/gradle.properties deleted file mode 100644 index dac8f00007..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/gradle.properties +++ /dev/null @@ -1,18 +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. -# - -pluginType=storage -pluginName=mongodb \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/client/MongodbClientManager.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/client/MongodbClientManager.java deleted file mode 100644 index 41aa544853..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/client/MongodbClientManager.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.client; - -import com.mongodb.ConnectionString; -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoClients; - -public class MongodbClientManager { - /** - * create mongodb client - * - * @param url url, like: mongodb://root:root@192.168.74.143:27018,192.168.74.143:27019 - * @return mongodb client - */ - public static MongoClient createMongodbClient(String url) { - ConnectionString connectionString = new ConnectionString(url); - return MongoClients.create(connectionString); - } - - /** - * close mongodb client - * - * @param mongoClient mongodb client - */ - public static void closeMongodbClient(MongoClient mongoClient) { - mongoClient.close(); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/config/ConfigKey.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/config/ConfigKey.java deleted file mode 100644 index e5949f819f..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/config/ConfigKey.java +++ /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. - */ - -package org.apache.eventmesh.storage.mongodb.config; - -public class ConfigKey { - - public static final String STANDALONE = "STANDALONE"; - - public static final String REPLICA_SET = "REPLICA_SET"; -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/config/ConfigurationHolder.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/config/ConfigurationHolder.java deleted file mode 100644 index f42dc2cdad..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/config/ConfigurationHolder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.config; - -import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.common.config.ConfigFiled; - -import lombok.Data; - -@Data -@Config(prefix = "eventMesh.server.mongodb", path = "classPath://mongodb-client.properties") -public class ConfigurationHolder { - @ConfigFiled(field = "connectorType") - private String connectorType; - - @ConfigFiled(field = "url") - private String url; - - @ConfigFiled(field = "database") - private String database; - - @ConfigFiled(field = "collection") - private String collection; -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/constant/MongodbConstants.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/constant/MongodbConstants.java deleted file mode 100644 index 6af239bea5..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/constant/MongodbConstants.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 org.apache.eventmesh.storage.mongodb.constant; - -public class MongodbConstants { - public static final String TOPIC = "flag"; - public static final String CAPPED_COL_TOPIC_FN = "topic"; - public static final String CAPPED_COL_CURSOR_FN = "ts"; - public static final String SEQUENCE_COLLECTION_NAME = "pub_sub_seq"; - public static final String SEQUENCE_KEY_FN = "topic"; - public static final String SEQUENCE_VALUE_FN = "value"; - -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/consumer/MongodbConsumer.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/consumer/MongodbConsumer.java deleted file mode 100644 index 0484b7b4a3..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/consumer/MongodbConsumer.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.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.config.Config; -import org.apache.eventmesh.storage.mongodb.config.ConfigKey; -import org.apache.eventmesh.storage.mongodb.config.ConfigurationHolder; - -import java.util.List; -import java.util.Properties; - -import io.cloudevents.CloudEvent; - -@Config(field = "configurationHolder") -public class MongodbConsumer implements Consumer { - - private ConfigurationHolder configurationHolder; - - private Consumer consumer; - - @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 { - String connectorType = configurationHolder.getConnectorType(); - if (connectorType.equals(ConfigKey.STANDALONE)) { - consumer = new MongodbStandaloneConsumer(configurationHolder); - } - if (connectorType.equals(ConfigKey.REPLICA_SET)) { - consumer = new MongodbReplicaSetConsumer(configurationHolder); - } - consumer.init(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-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/consumer/MongodbReplicaSetConsumer.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/consumer/MongodbReplicaSetConsumer.java deleted file mode 100644 index d67899bc6f..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/consumer/MongodbReplicaSetConsumer.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.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.consumer.Consumer; -import org.apache.eventmesh.storage.mongodb.client.MongodbClientManager; -import org.apache.eventmesh.storage.mongodb.config.ConfigurationHolder; -import org.apache.eventmesh.storage.mongodb.utils.MongodbCloudEventUtil; - -import java.util.List; -import java.util.Properties; - -import org.bson.Document; - -import io.cloudevents.CloudEvent; - -import com.mongodb.client.ChangeStreamIterable; -import com.mongodb.client.MongoChangeStreamCursor; -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoCollection; -import com.mongodb.client.model.changestream.ChangeStreamDocument; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class MongodbReplicaSetConsumer implements Consumer { - private final ConfigurationHolder configurationHolder; - - private MongoClient mongoClient; - - private MongoChangeStreamCursor> cursor; - - private volatile boolean started = false; - - private EventListener eventListener; - - public MongodbReplicaSetConsumer(ConfigurationHolder configurationHolder) { - this.configurationHolder = configurationHolder; - } - - @Override - public boolean isStarted() { - return started; - } - - @Override - public boolean isClosed() { - return !isStarted(); - } - - @Override - public void start() { - if (!started) { - started = true; - } - } - - @Override - public void shutdown() { - if (started) { - try { - if (this.mongoClient != null) { - MongodbClientManager.closeMongodbClient(this.mongoClient); - } - if (this.cursor != null) { - this.cursor.close(); - } - } finally { - started = false; - } - } - } - - @Override - public void init(Properties keyValue) { - this.mongoClient = MongodbClientManager.createMongodbClient(configurationHolder.getUrl()); - } - - @Override - public void updateOffset(List cloudEvents, AbstractContext context) { - - } - - @Override - public void subscribe(String topic) { - MongoCollection collection = mongoClient - .getDatabase(configurationHolder.getDatabase()).getCollection(configurationHolder.getCollection()); - ChangeStreamIterable changeStreamDocuments = collection.watch(); - this.cursor = changeStreamDocuments.cursor(); - this.handle(); - } - - @Override - public void unsubscribe(String topic) { - this.cursor.close(); - } - - @Override - public void registerEventListener(EventListener listener) { - this.eventListener = listener; - } - - private void handle() { - while (this.cursor.hasNext()) { - ChangeStreamDocument next = cursor.next(); - Document fullDocument = next.getFullDocument(); - if (fullDocument != null) { - CloudEvent cloudEvent = MongodbCloudEventUtil.convertToCloudEvent(fullDocument); - final EventMeshAsyncConsumeContext consumeContext = new EventMeshAsyncConsumeContext() { - @Override - public void commit(EventMeshAction action) { - log.info("[MongodbReplicaSetConsumer] Mongodb consumer context commit."); - } - }; - if (eventListener != null) { - eventListener.consume(cloudEvent, consumeContext); - } - } - } - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/consumer/MongodbStandaloneConsumer.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/consumer/MongodbStandaloneConsumer.java deleted file mode 100644 index 9722923ae9..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/consumer/MongodbStandaloneConsumer.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 org.apache.eventmesh.storage.mongodb.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.consumer.Consumer; -import org.apache.eventmesh.common.ThreadPoolFactory; -import org.apache.eventmesh.storage.mongodb.client.MongodbClientManager; -import org.apache.eventmesh.storage.mongodb.config.ConfigurationHolder; -import org.apache.eventmesh.storage.mongodb.constant.MongodbConstants; -import org.apache.eventmesh.storage.mongodb.utils.MongodbCloudEventUtil; - -import java.util.List; -import java.util.Properties; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.bson.Document; - -import io.cloudevents.CloudEvent; - -import com.mongodb.client.FindIterable; -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoCollection; -import com.mongodb.client.MongoDatabase; - -import lombok.extern.slf4j.Slf4j; -@Slf4j -@SuppressWarnings("all") -public class MongodbStandaloneConsumer implements Consumer { - - private final ConfigurationHolder configurationHolder; - - private volatile boolean started = false; - - private EventListener eventListener; - - private MongoClient client; - - private MongoDatabase db; - - private MongoCollection cappedCol; - - private SubTask task = new SubTask(); - - private final ThreadPoolExecutor executor = ThreadPoolFactory.createThreadPoolExecutor( - Runtime.getRuntime().availableProcessors() * 2, - Runtime.getRuntime().availableProcessors() * 2, - "EventMesh-Mongodb-StandaloneConsumer-"); - - public MongodbStandaloneConsumer(ConfigurationHolder configurationHolder) { - this.configurationHolder = configurationHolder; - } - - @Override - public boolean isStarted() { - return started; - } - - @Override - public boolean isClosed() { - return !isStarted(); - } - - @Override - public void start() { - if (!started) { - started = true; - } - } - - @Override - public void shutdown() { - if (started) { - try { - MongodbClientManager.closeMongodbClient(this.client); - } finally { - started = false; - } - } - } - - @Override - public void init(Properties keyValue) { - this.client = MongodbClientManager.createMongodbClient(configurationHolder.getUrl()); - this.db = client.getDatabase(configurationHolder.getDatabase()); - this.cappedCol = db.getCollection(configurationHolder.getCollection()); - //create index - Document index = new Document(MongodbConstants.CAPPED_COL_CURSOR_FN, 1) - .append(MongodbConstants.CAPPED_COL_TOPIC_FN, 1); - this.cappedCol.createIndex(index); - } - - @Override - public void updateOffset(List cloudEvents, AbstractContext context) { - - } - - @Override - public void subscribe(String topic) { - task = new SubTask(); - executor.execute(task); - } - - @Override - public void unsubscribe(String topic) { - task.stop(); - } - - @Override - public void registerEventListener(EventListener listener) { - this.eventListener = listener; - } - - private FindIterable getCursor(MongoCollection collection, String topic, int lastId) { - Document index = new Document("$gt", lastId); - Document ts = new Document(MongodbConstants.CAPPED_COL_CURSOR_FN, index); - - Document spec = ts.append(MongodbConstants.CAPPED_COL_TOPIC_FN, topic); - FindIterable documents = collection.find(spec); - return documents; - } - - private class SubTask implements Runnable { - private final AtomicBoolean stop = new AtomicBoolean(false); - - public void run() { - int lastId = -1; - while (!stop.get()) { - try { - FindIterable cur = getCursor(cappedCol, MongodbConstants.TOPIC, lastId); - for (Document obj : cur) { - CloudEvent cloudEvent = MongodbCloudEventUtil.convertToCloudEvent(obj); - final EventMeshAsyncConsumeContext consumeContext = new EventMeshAsyncConsumeContext() { - @Override - public void commit(EventMeshAction action) { - log.info("[MongodbStandaloneConsumer] Mongodb consumer context commit."); - } - }; - if (eventListener != null) { - eventListener.consume(cloudEvent, consumeContext); - } - try { - lastId = (int) ((Double) obj.get(MongodbConstants.CAPPED_COL_CURSOR_FN)).doubleValue(); - } catch (ClassCastException ce) { - lastId = (Integer) obj.get(MongodbConstants.CAPPED_COL_CURSOR_FN); - } - } - } catch (Exception ex) { - log.error("[MongodbStandaloneConsumer] thread run happen exception.", ex); - } - Thread.yield(); - } - } - - public void stop() { - stop.set(true); - } - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/exception/MongodbStorageException.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/exception/MongodbStorageException.java deleted file mode 100644 index e9dfe6794b..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/exception/MongodbStorageException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.exception; - -import org.apache.eventmesh.api.exception.StorageRuntimeException; - -public class MongodbStorageException extends StorageRuntimeException { - - public MongodbStorageException(String message) { - super(message); - } - - public MongodbStorageException(Throwable throwable) { - super(throwable); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/producer/MongodbProducer.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/producer/MongodbProducer.java deleted file mode 100644 index 84e6fa7a88..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/producer/MongodbProducer.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.producer; - -import org.apache.eventmesh.api.RequestReplyCallback; -import org.apache.eventmesh.api.SendCallback; -import org.apache.eventmesh.api.producer.Producer; -import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.storage.mongodb.config.ConfigKey; -import org.apache.eventmesh.storage.mongodb.config.ConfigurationHolder; - -import java.util.Properties; - -import io.cloudevents.CloudEvent; - -@Config(field = "configurationHolder") -public class MongodbProducer implements Producer { - - private ConfigurationHolder configurationHolder; - - private Producer producer; - - @Override - public boolean isStarted() { - return producer.isStarted(); - } - - @Override - public boolean isClosed() { - return producer.isClosed(); - } - - @Override - public void start() { - producer.start(); - } - - @Override - public void shutdown() { - producer.shutdown(); - } - - @Override - public void init(Properties properties) throws Exception { - String connectorType = configurationHolder.getConnectorType(); - if (connectorType.equals(ConfigKey.STANDALONE)) { - producer = new MongodbStandaloneProducer(configurationHolder); - } - if (connectorType.equals(ConfigKey.REPLICA_SET)) { - producer = new MongodbReplicaSetProducer(configurationHolder); - } - producer.init(properties); - } - - @Override - public void publish(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { - producer.publish(cloudEvent, sendCallback); - } - - @Override - public void sendOneway(CloudEvent cloudEvent) { - producer.sendOneway(cloudEvent); - } - - @Override - public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) throws Exception { - producer.request(cloudEvent, rrCallback, timeout); - } - - @Override - public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { - return producer.reply(cloudEvent, sendCallback); - } - - @Override - public void checkTopicExist(String topic) throws Exception { - producer.checkTopicExist(topic); - } - - @Override - public void setExtFields() { - producer.setExtFields(); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/producer/MongodbReplicaSetProducer.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/producer/MongodbReplicaSetProducer.java deleted file mode 100644 index 4588968003..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/producer/MongodbReplicaSetProducer.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.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.OnExceptionContext; -import org.apache.eventmesh.api.producer.Producer; -import org.apache.eventmesh.storage.mongodb.client.MongodbClientManager; -import org.apache.eventmesh.storage.mongodb.config.ConfigurationHolder; -import org.apache.eventmesh.storage.mongodb.exception.MongodbStorageException; -import org.apache.eventmesh.storage.mongodb.utils.MongodbCloudEventUtil; - -import java.util.Properties; - -import org.bson.Document; - -import io.cloudevents.CloudEvent; - -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoCollection; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class MongodbReplicaSetProducer implements Producer { - private volatile boolean started = false; - - private final ConfigurationHolder configurationHolder; - - private MongoClient mongoClient; - - public MongodbReplicaSetProducer(ConfigurationHolder configurationHolder) { - this.configurationHolder = configurationHolder; - } - - @Override - public boolean isStarted() { - return started; - } - - @Override - public boolean isClosed() { - return !isStarted(); - } - - @Override - public void start() { - if (!started) { - started = true; - } - } - - @Override - public void shutdown() { - if (started) { - try { - if (this.mongoClient != null) { - MongodbClientManager.closeMongodbClient(this.mongoClient); - } - } finally { - started = false; - } - } - } - - @Override - public void init(Properties properties) { - this.mongoClient = MongodbClientManager.createMongodbClient(configurationHolder.getUrl()); - } - - @Override - public void publish(CloudEvent cloudEvent, SendCallback sendCallback) { - try { - Document document = MongodbCloudEventUtil.convertToDocument(cloudEvent); - MongoCollection collection = mongoClient - .getDatabase(configurationHolder.getDatabase()).getCollection(configurationHolder.getCollection()); - collection.insertOne(document); - - SendResult sendResult = new SendResult(); - sendResult.setTopic(cloudEvent.getSubject()); - sendResult.setMessageId(cloudEvent.getId()); - sendCallback.onSuccess(sendResult); - } catch (Exception ex) { - log.error("[MongodbReplicaSetProducer] publish happen exception.", ex); - sendCallback.onException( - OnExceptionContext.builder() - .topic(cloudEvent.getSubject()) - .messageId(cloudEvent.getId()) - .exception(new MongodbStorageException(ex)) - .build() - ); - } - } - - @Override - public void sendOneway(CloudEvent cloudEvent) { - try { - Document document = MongodbCloudEventUtil.convertToDocument(cloudEvent); - MongoCollection collection = mongoClient - .getDatabase(configurationHolder.getDatabase()).getCollection(configurationHolder.getCollection()); - collection.insertOne(document); - } catch (Exception ex) { - log.error("[MongodbReplicaSetProducer] sendOneway happen exception.", ex); - } - } - - @Override - public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) { - - } - - @Override - public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback) { - return false; - } - - @Override - public void checkTopicExist(String topic) { - - } - - @Override - public void setExtFields() { - - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/producer/MongodbStandaloneProducer.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/producer/MongodbStandaloneProducer.java deleted file mode 100644 index 5a8e99812d..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/producer/MongodbStandaloneProducer.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.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.OnExceptionContext; -import org.apache.eventmesh.api.producer.Producer; -import org.apache.eventmesh.storage.mongodb.client.MongodbClientManager; -import org.apache.eventmesh.storage.mongodb.config.ConfigurationHolder; -import org.apache.eventmesh.storage.mongodb.constant.MongodbConstants; -import org.apache.eventmesh.storage.mongodb.exception.MongodbStorageException; -import org.apache.eventmesh.storage.mongodb.utils.MongodbCloudEventUtil; -import org.apache.eventmesh.storage.mongodb.utils.MongodbSequenceUtil; - -import java.util.Properties; - -import org.bson.Document; - -import io.cloudevents.CloudEvent; - -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoCollection; -import com.mongodb.client.MongoDatabase; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@SuppressWarnings("all") -public class MongodbStandaloneProducer implements Producer { - - private final ConfigurationHolder configurationHolder; - - private volatile boolean started = false; - - private MongoClient client; - - private MongoDatabase db; - - private MongoCollection cappedCol; - - private MongodbSequenceUtil mongodbSequenceUtil; - - public MongodbStandaloneProducer(ConfigurationHolder configurationHolder) { - this.configurationHolder = configurationHolder; - } - - @Override - public boolean isStarted() { - return started; - } - - @Override - public boolean isClosed() { - return !isStarted(); - } - - @Override - public void start() { - if (!started) { - started = true; - } - } - - @Override - public void shutdown() { - if (started) { - try { - MongodbClientManager.closeMongodbClient(this.client); - } finally { - started = false; - } - } - } - - @Override - public void init(Properties keyValue) { - this.client = MongodbClientManager.createMongodbClient(configurationHolder.getUrl()); - this.db = client.getDatabase(configurationHolder.getDatabase()); - this.cappedCol = db.getCollection(configurationHolder.getCollection()); - this.mongodbSequenceUtil = new MongodbSequenceUtil(configurationHolder); - } - - @Override - public void publish(CloudEvent cloudEvent, SendCallback sendCallback) { - try { - Document doc = MongodbCloudEventUtil.convertToDocument(cloudEvent); - int i = mongodbSequenceUtil.getNextSeq(MongodbConstants.TOPIC); - doc.append(MongodbConstants.CAPPED_COL_TOPIC_FN, MongodbConstants.TOPIC) - .append(MongodbConstants.CAPPED_COL_CURSOR_FN, i); - cappedCol.insertOne(doc); - - SendResult sendResult = new SendResult(); - sendResult.setTopic(cloudEvent.getSubject()); - sendResult.setMessageId(cloudEvent.getId()); - sendCallback.onSuccess(sendResult); - } catch (Exception ex) { - log.error("[MongodbStandaloneProducer] publish happen exception.", ex); - sendCallback.onException( - OnExceptionContext.builder() - .topic(cloudEvent.getSubject()) - .messageId(cloudEvent.getId()) - .exception(new MongodbStorageException(ex)) - .build() - ); - } - } - - @Override - public void sendOneway(CloudEvent cloudEvent) { - try { - Document doc = MongodbCloudEventUtil.convertToDocument(cloudEvent); - int i = mongodbSequenceUtil.getNextSeq(MongodbConstants.TOPIC); - doc.append(MongodbConstants.CAPPED_COL_TOPIC_FN, MongodbConstants.TOPIC) - .append(MongodbConstants.CAPPED_COL_CURSOR_FN, i); - cappedCol.insertOne(doc); - } catch (Exception ex) { - log.error("[MongodbStandaloneProducer] sendOneway happen exception.", ex); - } - } - - @Override - public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) throws Exception { - - } - - @Override - public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { - return false; - } - - @Override - public void checkTopicExist(String topic) throws Exception { - - } - - @Override - public void setExtFields() { - - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/storage/MongodbStorageResourceService.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/storage/MongodbStorageResourceService.java deleted file mode 100644 index 8dcffc3353..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/storage/MongodbStorageResourceService.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 org.apache.eventmesh.storage.mongodb.storage; - -import org.apache.eventmesh.api.storage.StorageResourceService; - -public class MongodbStorageResourceService implements StorageResourceService { - @Override - public void init() throws Exception { - - } - - @Override - public void release() throws Exception { - - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/utils/MongodbCloudEventUtil.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/utils/MongodbCloudEventUtil.java deleted file mode 100644 index b42626f674..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/utils/MongodbCloudEventUtil.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.utils; - -import org.apache.eventmesh.storage.mongodb.exception.MongodbStorageException; - -import java.net.URI; -import java.nio.charset.StandardCharsets; - -import org.bson.Document; - -import io.cloudevents.CloudEvent; -import io.cloudevents.SpecVersion; -import io.cloudevents.core.builder.CloudEventBuilder; - -public class MongodbCloudEventUtil { - public static CloudEvent convertToCloudEvent(Document document) { - document.remove("_id"); - String versionStr = document.getString("version"); - SpecVersion version = SpecVersion.valueOf(versionStr); - CloudEventBuilder builder; - switch (version) { - case V03: - builder = CloudEventBuilder.v03(); - break; - case V1: - builder = CloudEventBuilder.v1(); - break; - default: - throw new MongodbStorageException(String.format("CloudEvent version %s does not support.", version)); - } - builder.withData(document.remove("data").toString().getBytes()) - .withId(document.remove("id").toString()) - .withSource(URI.create(document.remove("source").toString())) - .withType(document.remove("type").toString()) - .withDataContentType(document.remove("datacontenttype").toString()) - .withSubject(document.remove("subject").toString()); - document.forEach((key, value) -> builder.withExtension(key, value.toString())); - - return builder.build(); - } - - public static Document convertToDocument(CloudEvent cloudEvent) { - Document document = new Document(); - document.put("version", cloudEvent.getSpecVersion().name()); - document.put("data", cloudEvent.getData() == null - ? null : new String(cloudEvent.getData().toBytes(), StandardCharsets.UTF_8)); - document.put("id", cloudEvent.getId()); - document.put("source", cloudEvent.getSource().toString()); - document.put("type", cloudEvent.getType()); - document.put("datacontenttype", cloudEvent.getDataContentType()); - document.put("subject", cloudEvent.getSubject()); - cloudEvent.getExtensionNames().forEach(key -> document.put(key, cloudEvent.getExtension(key))); - - return document; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/utils/MongodbSequenceUtil.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/utils/MongodbSequenceUtil.java deleted file mode 100644 index 9eb58aa1ed..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/java/org/apache/eventmesh/storage/mongodb/utils/MongodbSequenceUtil.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb.utils; - -import org.apache.eventmesh.storage.mongodb.client.MongodbClientManager; -import org.apache.eventmesh.storage.mongodb.config.ConfigurationHolder; -import org.apache.eventmesh.storage.mongodb.constant.MongodbConstants; - -import org.bson.Document; - -import com.mongodb.BasicDBObject; -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoCollection; -import com.mongodb.client.MongoDatabase; -import com.mongodb.client.model.FindOneAndUpdateOptions; -import com.mongodb.client.model.ReturnDocument; - -@SuppressWarnings("all") -public class MongodbSequenceUtil { - private final MongoClient mongoClient; - private final MongoDatabase db; - private final MongoCollection seqCol; - - public MongodbSequenceUtil(ConfigurationHolder configurationHolder) { - mongoClient = MongodbClientManager.createMongodbClient(configurationHolder.getUrl()); - db = mongoClient.getDatabase(configurationHolder.getDatabase()); - seqCol = db.getCollection(MongodbConstants.SEQUENCE_COLLECTION_NAME); - } - - public int getNextSeq(String topic) { - Document query = new Document(MongodbConstants.SEQUENCE_KEY_FN, topic); - Document update = new Document("$inc", new BasicDBObject(MongodbConstants.SEQUENCE_VALUE_FN, 1)); - FindOneAndUpdateOptions options = new FindOneAndUpdateOptions(); - options.upsert(true); - options.returnDocument(ReturnDocument.AFTER); - Document result = seqCol.findOneAndUpdate(query, update, options); - return (int) (Integer) result.get(MongodbConstants.SEQUENCE_VALUE_FN); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer deleted file mode 100644 index a405ee7bf7..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer +++ /dev/null @@ -1,16 +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. - -mongodb=org.apache.eventmesh.storage.mongodb.consumer.MongodbConsumer \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer deleted file mode 100644 index f7c627f988..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer +++ /dev/null @@ -1,16 +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. - -mongodb=org.apache.eventmesh.storage.mongodb.producer.MongodbProducer \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService deleted file mode 100644 index ea0ae79397..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService +++ /dev/null @@ -1,16 +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. - -mongodb=org.apache.eventmesh.storage.mongodb.storage.MongodbStorageResourceService \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/mongodb-client.properties b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/mongodb-client.properties deleted file mode 100644 index 70afeb8dba..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/main/resources/mongodb-client.properties +++ /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. -# - -####################### mongodb server ################## -eventMesh.server.mongodb.connectorType=STANDALONE -##like: mongodb://root:root@127.0.0.1:27018,127.0.0.1:27019 -eventMesh.server.mongodb.url=mongodb://127.0.0.1:27018 -eventMesh.server.mongodb.database=db -eventMesh.server.mongodb.collection=col - -#eventMesh.server.mongodb.connectorType=REPLICA_SET -##like: mongodb://root:root@127.0.0.1:27018,127.0.0.1:27019 -#eventMesh.server.mongodb.url=mongodb://root:root@127.0.0.1:27018,127.0.0.1:27019 -#eventMesh.server.mongodb.database=db -#eventMesh.server.mongodb.collection=col \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/java/org/apache/eventmesh/storage/mongodb/MongodbConnectorTest.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/java/org/apache/eventmesh/storage/mongodb/MongodbConnectorTest.java deleted file mode 100644 index 8ba1ce3cd6..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/java/org/apache/eventmesh/storage/mongodb/MongodbConnectorTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.mongodb; - -import org.apache.eventmesh.api.EventMeshAction; -import org.apache.eventmesh.api.SendCallback; -import org.apache.eventmesh.api.SendResult; -import org.apache.eventmesh.api.exception.OnExceptionContext; - -import java.net.URI; -import java.time.OffsetDateTime; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import org.junit.Assert; -import org.junit.Test; - -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; - -public class MongodbConnectorTest extends MongodbServer { - @Test - public void subscribe() throws Exception { - final int expectedCount = 5; - final CountDownLatch downLatch = new CountDownLatch(expectedCount); - - mongodbConsumer.registerEventListener((cloudEvent, context) -> { - downLatch.countDown(); - context.commit(EventMeshAction.CommitMessage); - Assert.assertEquals(cloudEvent.getSubject(), "topic"); - }); - - mongodbConsumer.subscribe("topic"); - - Thread.sleep(1000); - for (int i = 0; i < expectedCount; i++) { - CloudEvent cloudEvent = CloudEventBuilder.v1() - .withId(String.valueOf(i)) - .withTime(OffsetDateTime.now()) - .withSource(URI.create("testsource")) - .withSubject("topic") - .withType(String.class.getCanonicalName()) - .withDataContentType("text/plain") - .withData("data".getBytes()) - .build(); - - mongodbProducer.publish(cloudEvent, new SendCallback() { - @Override - public void onSuccess(SendResult sendResult) { - Assert.assertEquals(cloudEvent.getId(), sendResult.getMessageId()); - Assert.assertEquals(cloudEvent.getSubject(), sendResult.getTopic()); - } - - @Override - public void onException(OnExceptionContext context) { - Assert.assertEquals(cloudEvent.getId(), context.getMessageId()); - Assert.assertEquals(cloudEvent.getSubject(), context.getTopic()); - } - }); - } - - Assert.assertTrue(downLatch.await(5, TimeUnit.MINUTES)); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/java/org/apache/eventmesh/storage/mongodb/MongodbServer.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/java/org/apache/eventmesh/storage/mongodb/MongodbServer.java deleted file mode 100644 index 51094442aa..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/java/org/apache/eventmesh/storage/mongodb/MongodbServer.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 org.apache.eventmesh.storage.mongodb; - -import org.apache.eventmesh.api.factory.StoragePluginFactory; -import org.apache.eventmesh.storage.mongodb.consumer.MongodbConsumer; -import org.apache.eventmesh.storage.mongodb.producer.MongodbProducer; - -import java.util.Properties; - -import org.junit.After; -import org.junit.Before; - -import de.bwaldvogel.mongo.MongoServer; -import de.bwaldvogel.mongo.backend.memory.MemoryBackend; - -public class MongodbServer { - private MongoServer server1; - private MongoServer server2; - public MongodbConsumer mongodbConsumer; - public MongodbProducer mongodbProducer; - - @Before - public void setup() throws Exception { - server1 = new MongoServer(new MemoryBackend()); - server1.bind("127.0.0.1", 27018); - server2 = new MongoServer(new MemoryBackend()); - server2.bind("127.0.0.1", 27019); - - mongodbConsumer = (MongodbConsumer) StoragePluginFactory.getMeshMQPushConsumer("mongodb"); - mongodbConsumer.init(new Properties()); - mongodbConsumer.start(); - - mongodbProducer = (MongodbProducer) StoragePluginFactory.getMeshMQProducer("mongodb"); - mongodbProducer.init(new Properties()); - mongodbProducer.start(); - } - - @After - public void shutdown() { - mongodbConsumer.shutdown(); - mongodbProducer.shutdown(); - - server1.shutdown(); - server2.shutdown(); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/java/org/apache/eventmesh/storage/mongodb/MongodbServerTest.java b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/java/org/apache/eventmesh/storage/mongodb/MongodbServerTest.java deleted file mode 100644 index 5d3e6cdfb1..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/java/org/apache/eventmesh/storage/mongodb/MongodbServerTest.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 org.apache.eventmesh.storage.mongodb; - -import org.bson.Document; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoClients; -import com.mongodb.client.MongoCollection; - -import de.bwaldvogel.mongo.MongoServer; -import de.bwaldvogel.mongo.backend.memory.MemoryBackend; - -public class MongodbServerTest { - private MongoCollection collection; - private MongoClient client; - private MongoServer server; - - @Before - public void setUp() { - server = new MongoServer(new MemoryBackend()); - - // optionally: - // server.enableSsl(key, keyPassword, certificate); - // server.enableOplog(); - - // bind on a random local port - server.bind("127.0.0.1", 27011); - String connectionString = server.getConnectionString(); - - client = MongoClients.create(connectionString); - collection = client.getDatabase("testdb").getCollection("testcollection"); - } - - @After - public void tearDown() { - client.close(); - server.shutdown(); - } - - @Test - public void testSimpleInsertQuery() { - Assert.assertEquals(collection.countDocuments(), 0); - - // creates the database and collection in memory and insert the object - Document obj = new Document("_id", 1).append("key", "value"); - collection.insertOne(obj); - - Assert.assertEquals(collection.countDocuments(), 1L); - Assert.assertEquals(collection.find().first(), obj); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/resources/mongodb-client.properties b/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/resources/mongodb-client.properties deleted file mode 100644 index 70afeb8dba..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-mongodb/src/test/resources/mongodb-client.properties +++ /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. -# - -####################### mongodb server ################## -eventMesh.server.mongodb.connectorType=STANDALONE -##like: mongodb://root:root@127.0.0.1:27018,127.0.0.1:27019 -eventMesh.server.mongodb.url=mongodb://127.0.0.1:27018 -eventMesh.server.mongodb.database=db -eventMesh.server.mongodb.collection=col - -#eventMesh.server.mongodb.connectorType=REPLICA_SET -##like: mongodb://root:root@127.0.0.1:27018,127.0.0.1:27019 -#eventMesh.server.mongodb.url=mongodb://root:root@127.0.0.1:27018,127.0.0.1:27019 -#eventMesh.server.mongodb.database=db -#eventMesh.server.mongodb.collection=col \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/README.md b/eventmesh-storage-plugin/eventmesh-storage-pravega/README.md deleted file mode 100644 index 92306965b6..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Pravega Connector -Pravega connector of EventMesh supports taking Pravega as event storage. [Pravega](https://cncf.pravega.io/) is a storage system that exposes Stream as the main primitive for continuous and unbounded data and meets the requirement of EventMesh connector module. - -## The Design of Pravega Connector -Pravega has 3 level storage concepts, which are **Event**, **Stream**, **Scope**. An **Event** is represented as a set of bytes within a Stream. A **Stream** is a durable, elastic, append-only, unbounded sequence of bytes having good performance and strong consistency. A **Scope** acts as a namespace for Stream names and all Stream names are unique within their Scope. - -Naturally, Pravega connector makes each topic correspond to a pravega stream. Because `EventStreamWriter` and `EventStreamReader` must assign to a special stream in a special scope, each topic corresponds to an `EventStreamWriter` and a `ReaderGroup`(only contains one `EventStreamReader`) as well. What's more, `SubscribeTask` thread will read every topic stream continuously. - -**Note**: -- Publish success will respond `-1` as messageId since writing to Pravega will not return message offset of the stream. If you want to use EventMesh with Pravega, please ensure messageId is unimportant. -- Name and ID in Pravega must be `0-9`, `A-Z`, `a-z`, `.`, `-`. - - Topic must be legal in Pravega. - - ReaderGroup name format is `String.format("%s-%s", consumerGroup, topic)` for cluster message model, while random UUID for broadcast message model. - - Reader name format is `String.format("%s-reader", instanceName).replaceAll("\\(", "-").replaceAll("\\)", "-")`. The `instanceName` consists of `consumerGroup`, config `eventMesh.server.cluster`, EventMesh version and PID. - -![pravega-storage](./pravega-storage.jpg) - -## Active Pravega Connector -Referring to doc [_Build and Load Plugins_](https://eventmesh.apache.org/docs/installation/runtime#13-build-and-load-plugins) to load `:eventmesh-connector-plugin:eventmesh-connector-pravega` plugin module, and edit `eventMesh.connector.plugin.type=pravega` in config file `eventmesh.properties` to active pravega connector. \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/build.gradle b/eventmesh-storage-plugin/eventmesh-storage-pravega/build.gradle deleted file mode 100644 index 253c067203..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/build.gradle +++ /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. - */ - -configurations { - implementation.exclude group: 'ch.qos.logback', module: 'logback-classic' - implementation.exclude group: 'log4j', module: 'log4j' -} - -dependencies { - implementation project(":eventmesh-common") - implementation project(":eventmesh-storage-plugin:eventmesh-storage-api") - implementation("io.pravega:pravega-client:$pravega_version") { - exclude group: 'io.netty', module: 'netty-codec-http2:4.1.30.Final' - } - // use newer version to avoid CVE - implementation 'io.netty:netty-codec-http2' - - testImplementation "org.testcontainers:testcontainers:1.17.3" - - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - - testCompileOnly 'org.projectlombok:lombok' - testAnnotationProcessor 'org.projectlombok:lombok' -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/gradle.properties b/eventmesh-storage-plugin/eventmesh-storage-pravega/gradle.properties deleted file mode 100644 index 0bd75ae163..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/gradle.properties +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -pravega_version=0.11.0 - -pluginType=storage -pluginName=pravega \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/pravega-storage.jpg b/eventmesh-storage-plugin/eventmesh-storage-pravega/pravega-storage.jpg deleted file mode 100644 index 20cb829605..0000000000 Binary files a/eventmesh-storage-plugin/eventmesh-storage-pravega/pravega-storage.jpg and /dev/null differ diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/PravegaConsumerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/PravegaConsumerImpl.java deleted file mode 100644 index 2e8b2b6933..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/PravegaConsumerImpl.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.pravega; - -import org.apache.eventmesh.api.AbstractContext; -import org.apache.eventmesh.api.EventListener; -import org.apache.eventmesh.api.consumer.Consumer; -import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.storage.pravega.client.PravegaClient; -import org.apache.eventmesh.storage.pravega.config.PravegaStorageConfig; -import org.apache.eventmesh.storage.pravega.exception.PravegaStorageException; - -import java.util.List; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicBoolean; - -import io.cloudevents.CloudEvent; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Config(field = "pravegaConnectorConfig") -public class PravegaConsumerImpl implements Consumer { - - private static final AtomicBoolean started = new AtomicBoolean(false); - - /** - * Unified configuration class corresponding to pravega-storage.properties - */ - private PravegaStorageConfig pravegaConnectorConfig; - - private boolean isBroadcast; - private String instanceName; - private String consumerGroup; - private PravegaClient client; - private EventListener eventListener; - - @Override - public void init(Properties keyValue) throws Exception { - isBroadcast = Boolean.parseBoolean(keyValue.getProperty("isBroadcast", "false")); - instanceName = keyValue.getProperty("instanceName", ""); - consumerGroup = keyValue.getProperty("consumerGroup", ""); - - client = PravegaClient.getInstance(pravegaConnectorConfig); - } - - @Override - public void start() { - started.compareAndSet(false, true); - } - - @Override - public void shutdown() { - started.compareAndSet(true, false); - } - - @Override - public boolean isStarted() { - return started.get(); - } - - @Override - public boolean isClosed() { - return !started.get(); - } - - @Override - public void updateOffset(List cloudEvents, AbstractContext context) { - throw new UnsupportedOperationException(); - } - - @Override - public void subscribe(String topic) { - if (!client.subscribe(topic, isBroadcast, consumerGroup, instanceName, eventListener)) { - throw new PravegaStorageException(String.format("subscribe topic[%s] fail.", topic)); - } - } - - @Override - public void unsubscribe(String topic) { - if (!client.unsubscribe(topic, isBroadcast, consumerGroup)) { - throw new PravegaStorageException(String.format("unsubscribe topic[%s] fail.", topic)); - } - } - - @Override - public void registerEventListener(EventListener listener) { - this.eventListener = listener; - } - - public PravegaStorageConfig getClientConfiguration() { - return this.pravegaConnectorConfig; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/PravegaProducerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/PravegaProducerImpl.java deleted file mode 100644 index 707858d509..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/PravegaProducerImpl.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.pravega; - -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.api.exception.StorageRuntimeException; -import org.apache.eventmesh.api.producer.Producer; -import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.storage.pravega.client.PravegaClient; -import org.apache.eventmesh.storage.pravega.config.PravegaStorageConfig; -import org.apache.eventmesh.storage.pravega.exception.PravegaStorageException; - -import java.util.Properties; -import java.util.concurrent.atomic.AtomicBoolean; - -import io.cloudevents.CloudEvent; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Config(field = "pravegaConnectorConfig") -public class PravegaProducerImpl implements Producer { - - private final AtomicBoolean started = new AtomicBoolean(false); - private PravegaClient client; - - /** - * Unified configuration class corresponding to pravega-storage.properties - */ - private PravegaStorageConfig pravegaConnectorConfig; - - @Override - public void init(Properties properties) throws Exception { - client = PravegaClient.getInstance(pravegaConnectorConfig); - } - - @Override - public void start() { - started.compareAndSet(false, true); - } - - @Override - public void shutdown() { - started.compareAndSet(true, false); - } - - @Override - public boolean isStarted() { - return started.get(); - } - - @Override - public boolean isClosed() { - return !started.get(); - } - - @Override - public void publish(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { - try { - SendResult sendResult = client.publish(cloudEvent.getSubject(), cloudEvent); - sendCallback.onSuccess(sendResult); - } catch (Exception e) { - log.error("send message error, topic: {}", cloudEvent.getSubject()); - OnExceptionContext onExceptionContext = OnExceptionContext.builder() - .messageId("-1") - .topic(cloudEvent.getSubject()) - .exception(new StorageRuntimeException(e)) - .build(); - sendCallback.onException(onExceptionContext); - } - } - - @Override - public void sendOneway(CloudEvent cloudEvent) { - client.publish(cloudEvent.getSubject(), cloudEvent); - } - - @Override - public void request(CloudEvent cloudEvent, RequestReplyCallback rrCallback, long timeout) throws Exception { - throw new UnsupportedOperationException(); - } - - @Override - public boolean reply(CloudEvent cloudEvent, SendCallback sendCallback) throws Exception { - throw new UnsupportedOperationException(); - } - - @Override - public void checkTopicExist(String topic) throws Exception { - if (!client.checkTopicExist(topic)) { - throw new PravegaStorageException(String.format("topic:%s is not exist", topic)); - } - } - - @Override - public void setExtFields() { - - } - - public PravegaStorageConfig getClientConfiguration() { - return this.pravegaConnectorConfig; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/PravegaStorageResourceServiceImpl.java b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/PravegaStorageResourceServiceImpl.java deleted file mode 100644 index ab8225c91f..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/PravegaStorageResourceServiceImpl.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.pravega; - -import org.apache.eventmesh.api.storage.StorageResourceService; -import org.apache.eventmesh.storage.pravega.client.PravegaClient; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class PravegaStorageResourceServiceImpl implements StorageResourceService { - - @Override - public void init() throws Exception { - PravegaClient.getInstance().start(); - } - - @Override - public void release() throws Exception { - PravegaClient.getInstance().shutdown(); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/PravegaClient.java b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/PravegaClient.java deleted file mode 100644 index 401a19ea96..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/PravegaClient.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 org.apache.eventmesh.storage.pravega.client; - -import org.apache.eventmesh.api.EventListener; -import org.apache.eventmesh.api.SendResult; -import org.apache.eventmesh.storage.pravega.config.PravegaStorageConfig; -import org.apache.eventmesh.storage.pravega.exception.PravegaStorageException; - -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import io.cloudevents.CloudEvent; -import io.pravega.client.ClientConfig; -import io.pravega.client.EventStreamClientFactory; -import io.pravega.client.admin.ReaderGroupManager; -import io.pravega.client.admin.StreamManager; -import io.pravega.client.stream.EventStreamReader; -import io.pravega.client.stream.EventStreamWriter; -import io.pravega.client.stream.EventWriterConfig; -import io.pravega.client.stream.ReaderConfig; -import io.pravega.client.stream.ReaderGroupConfig; -import io.pravega.client.stream.StreamConfiguration; -import io.pravega.client.stream.impl.ByteArraySerializer; -import io.pravega.shared.NameUtils; -import io.pravega.shared.security.auth.DefaultCredentials; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class PravegaClient { - - private final PravegaStorageConfig config; - private final StreamManager streamManager; - private final EventStreamClientFactory clientFactory; - private final ReaderGroupManager readerGroupManager; - private final Map> writerMap = new ConcurrentHashMap<>(); - private final Map subscribeTaskMap = new ConcurrentHashMap<>(); - - private static PravegaClient instance; - - public static PravegaClient getInstance() { - return instance; - } - - public static PravegaClient getInstance(PravegaStorageConfig config) { - if (instance == null) { - instance = new PravegaClient(config); - } - - return instance; - } - - private PravegaClient(PravegaStorageConfig config) { - this.config = config; - streamManager = StreamManager.create(config.getControllerURI()); - ClientConfig.ClientConfigBuilder clientConfigBuilder = ClientConfig.builder().controllerURI(config.getControllerURI()); - if (config.isAuthEnabled()) { - clientConfigBuilder.credentials(new DefaultCredentials(config.getPassword(), config.getUsername())); - } - if (config.isTlsEnable()) { - clientConfigBuilder.trustStore(config.getTruststore()).validateHostName(false); - } - ClientConfig clientConfig = clientConfigBuilder.build(); - clientFactory = EventStreamClientFactory.withScope(config.getScope(), clientConfig); - readerGroupManager = ReaderGroupManager.withScope(config.getScope(), clientConfig); - } - - protected static PravegaClient getNewInstance(PravegaStorageConfig config) { - return new PravegaClient(config); - } - - public void start() { - if (createScope()) { - log.info("Create Pravega scope[{}] success.", config.getScope()); - } else { - log.info("Pravega scope[{}] has already been created.", config.getScope()); - } - } - - public void shutdown() { - subscribeTaskMap.forEach((topic, task) -> task.stopRead()); - subscribeTaskMap.clear(); - writerMap.forEach((topic, writer) -> writer.close()); - writerMap.clear(); - readerGroupManager.close(); - clientFactory.close(); - streamManager.close(); - } - - /** - * Publish CloudEvent to Pravega stream named topic. Note that the messageId in SendResult is always -1 since {@link - * EventStreamWriter#writeEvent(Object)} just return {@link java.util.concurrent.CompletableFuture} with {@link Void} which couldn't get - * messageId. - * - * @param topic topic - * @param cloudEvent cloudEvent - * @return SendResult whose messageId is always -1 - */ - public SendResult publish(String topic, CloudEvent cloudEvent) { - if (!createStream(topic)) { - log.debug("stream[{}] has already been created.", topic); - } - EventStreamWriter writer = writerMap.computeIfAbsent(topic, k -> createWrite(topic)); - PravegaCloudEventWriter cloudEventWriter = new PravegaCloudEventWriter(topic); - PravegaEvent pravegaEvent = cloudEventWriter.writeBinary(cloudEvent); - try { - writer.writeEvent(PravegaEvent.toByteArray(pravegaEvent)).get(5, TimeUnit.SECONDS); - } catch (ExecutionException | InterruptedException | TimeoutException e) { - log.error(String.format("Write topic[%s] fail.", topic), e); - throw new PravegaStorageException(String.format("Write topic[%s] fail.", topic)); - } - SendResult sendResult = new SendResult(); - sendResult.setTopic(topic); - // set -1 as messageId since writeEvent method doesn't return it. - sendResult.setMessageId("-1"); - return sendResult; - - } - - public boolean subscribe(String topic, boolean isBroadcast, String consumerGroup, String instanceName, EventListener listener) { - if (subscribeTaskMap.containsKey(topic)) { - return true; - } - String readerGroupName = buildReaderGroupName(isBroadcast, consumerGroup, topic); - createReaderGroup(topic, readerGroupName); - String readerId = buildReaderId(instanceName); - EventStreamReader reader = createReader(readerId, readerGroupName); - SubscribeTask subscribeTask = new SubscribeTask(topic, reader, listener); - subscribeTask.start(); - subscribeTaskMap.put(topic, subscribeTask); - return true; - } - - public boolean unsubscribe(String topic, boolean isBroadcast, String consumerGroup) { - if (!subscribeTaskMap.containsKey(topic)) { - return true; - } - if (!isBroadcast) { - deleteReaderGroup(buildReaderGroupName(false, consumerGroup, topic)); - } - subscribeTaskMap.remove(topic).stopRead(); - return true; - } - - public boolean checkTopicExist(String topic) { - return streamManager.checkStreamExists(config.getScope(), topic); - } - - private boolean createScope() { - return streamManager.createScope(config.getScope()); - } - - private boolean createStream(String topic) { - StreamConfiguration streamConfiguration = StreamConfiguration.builder().build(); - return streamManager.createStream(config.getScope(), topic, streamConfiguration); - } - - private EventStreamWriter createWrite(String topic) { - return clientFactory.createEventWriter(topic, new ByteArraySerializer(), EventWriterConfig.builder().build()); - } - - private String buildReaderGroupName(boolean isBroadcast, String consumerGroup, String topic) { - if (isBroadcast) { - return UUID.randomUUID().toString(); - } else { - return String.format("%s-%s", consumerGroup, topic); - } - } - - private String buildReaderId(String instanceName) { - return String.format("%s-reader", instanceName).replace("\\(", "-").replace("\\)", "-"); - } - - private void createReaderGroup(String topic, String readerGroupName) { - if (!checkTopicExist(topic)) { - createStream(topic); - } - ReaderGroupConfig readerGroupConfig = - ReaderGroupConfig.builder() - .stream(NameUtils.getScopedStreamName(config.getScope(), topic)) - .retentionType(ReaderGroupConfig.StreamDataRetention.AUTOMATIC_RELEASE_AT_LAST_CHECKPOINT) - .build(); - readerGroupManager.createReaderGroup(readerGroupName, readerGroupConfig); - } - - private void deleteReaderGroup(String readerGroup) { - readerGroupManager.deleteReaderGroup(readerGroup); - } - - private EventStreamReader createReader(String readerId, String readerGroup) { - return clientFactory.createReader(readerId, readerGroup, new ByteArraySerializer(), ReaderConfig.builder().build()); - } - - protected StreamManager getStreamManager() { - return streamManager; - } - - protected EventStreamClientFactory getClientFactory() { - return clientFactory; - } - - protected ReaderGroupManager getReaderGroupManager() { - return readerGroupManager; - } - - public Map> getWriterMap() { - return writerMap; - } - - protected Map getSubscribeTaskMap() { - return subscribeTaskMap; - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/SubscribeTask.java b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/SubscribeTask.java deleted file mode 100644 index 4f26ff85e9..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/client/SubscribeTask.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.pravega.client; - -import org.apache.eventmesh.api.EventListener; -import org.apache.eventmesh.api.EventMeshAction; -import org.apache.eventmesh.api.EventMeshAsyncConsumeContext; - -import java.util.concurrent.atomic.AtomicBoolean; - -import io.cloudevents.CloudEvent; -import io.pravega.client.stream.EventRead; -import io.pravega.client.stream.EventStreamReader; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class SubscribeTask extends Thread { - - private final EventStreamReader reader; - private final EventListener listener; - private final AtomicBoolean running = new AtomicBoolean(true); - private final AtomicBoolean continueRead = new AtomicBoolean(true); - - public SubscribeTask(String name, EventStreamReader reader, EventListener listener) { - super(name); - this.reader = reader; - this.listener = listener; - } - - @Override - public void run() { - CloudEvent cloudEvent = null; - while (running.get()) { - if (continueRead.get()) { - EventRead event = reader.readNextEvent(2000); - - byte[] eventByteArray = event.getEvent(); - if (eventByteArray == null) { - continue; - } - PravegaEvent pravegaEvent = PravegaEvent.getFromByteArray(eventByteArray); - cloudEvent = pravegaEvent.convertToCloudEvent(); - - } - listener.consume(cloudEvent, new PravegaEventMeshAsyncConsumeContext()); - } - } - - public void stopRead() { - running.compareAndSet(true, false); - } - - private class PravegaEventMeshAsyncConsumeContext extends EventMeshAsyncConsumeContext { - - @Override - public void commit(EventMeshAction action) { - switch (action) { - case CommitMessage: - case ReconsumeLater: - continueRead.set(false); - break; - case ManualAck: - continueRead.set(true); - break; - default: - } - } - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/config/PravegaStorageConfig.java b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/config/PravegaStorageConfig.java deleted file mode 100644 index 646d021f01..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/config/PravegaStorageConfig.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.pravega.config; - -import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.common.config.ConfigFiled; - -import org.apache.commons.lang3.StringUtils; - -import java.net.URI; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -@Config(prefix = "eventMesh.server.pravega", path = "classPath://pravega-storage.properties") -public class PravegaStorageConfig { - - @ConfigFiled(field = "controller.uri") - private URI controllerURI = URI.create("tcp://127.0.0.1:9090"); - - @ConfigFiled(field = "scope") - private String scope = "eventmesh-pravega"; - - @ConfigFiled(field = "clientPool.size") - private int clientPoolSize = 8; - - @ConfigFiled(field = "queue.size") - private int queueSize = 512; - - @ConfigFiled(field = "authEnabled", reload = true) - private boolean authEnabled = false; - - @ConfigFiled(field = "username") - private String username = ""; - - @ConfigFiled(field = "password") - private String password = ""; - - @ConfigFiled(field = "tlsEnabled") - private boolean tlsEnable = false; - - @ConfigFiled(field = "truststore") - private String truststore = ""; - - public void reload() { - if (!authEnabled && StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) { - authEnabled = true; - } - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/exception/PravegaStorageException.java b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/exception/PravegaStorageException.java deleted file mode 100644 index 50d23cbba5..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/java/org/apache/eventmesh/storage/pravega/exception/PravegaStorageException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.pravega.exception; - -import org.apache.eventmesh.api.exception.StorageRuntimeException; - -public class PravegaStorageException extends StorageRuntimeException { - - public PravegaStorageException(String message) { - super(message); - } - - public PravegaStorageException(Throwable throwable) { - super(throwable); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer deleted file mode 100644 index 2d68877d38..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.consumer.Consumer +++ /dev/null @@ -1,16 +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. - -pravega=org.apache.eventmesh.storage.pravega.PravegaConsumerImpl \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer deleted file mode 100644 index b35a24cd4e..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.producer.Producer +++ /dev/null @@ -1,16 +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. - -pravega=org.apache.eventmesh.storage.pravega.PravegaProducerImpl \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService deleted file mode 100644 index 64222b4dc8..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.storage.StorageResourceService +++ /dev/null @@ -1,16 +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. - -pravega=org.apache.eventmesh.storage.pravega.PravegaStorageResourceServiceImpl \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/pravega-storage.properties b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/pravega-storage.properties deleted file mode 100644 index 25fa6f0af4..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/main/resources/pravega-storage.properties +++ /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. -# -#######################pravega-client################## -eventMesh.server.pravega.controller.uri=tcp://127.0.0.1:9090 -eventMesh.server.pravega.scope=eventmesh-pravega -eventMesh.server.pravega.authEnabled=false -eventMesh.server.pravega.username= -eventMesh.server.pravega.password= -eventMesh.server.pravega.tlsEnabled=false -eventMesh.server.pravega.truststore= -eventMesh.server.pravega.clientPool.size=8 -eventMesh.server.pravega.queue.size=512 \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/test/java/org/apache/eventmesh/storage/pravega/client/PravegaClientTest.java b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/test/java/org/apache/eventmesh/storage/pravega/client/PravegaClientTest.java deleted file mode 100644 index 594d1e0fd9..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/test/java/org/apache/eventmesh/storage/pravega/client/PravegaClientTest.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.pravega.client; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.apache.eventmesh.api.AsyncConsumeContext; -import org.apache.eventmesh.api.EventListener; -import org.apache.eventmesh.common.config.ConfigService; -import org.apache.eventmesh.storage.pravega.config.PravegaStorageConfig; - -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.function.Consumer; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.utility.DockerImageName; - -import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; -import io.pravega.client.admin.StreamManager; -import io.pravega.client.stream.ReaderGroupNotFoundException; - -import com.github.dockerjava.api.command.CreateContainerCmd; -import com.github.dockerjava.api.model.PortBinding; - -@Ignore -public class PravegaClientTest { - - private StreamManager streamManager; - private PravegaStorageConfig config; - private URI controllerURI; - - @Rule - public GenericContainer pravega = - new GenericContainer(DockerImageName.parse("pravega/pravega:0.11.0")) - .withExposedPorts(9090, 12345).withEnv("HOST_IP", "127.0.0.1").withCommand("standalone") - .withCreateContainerCmdModifier((Consumer) createContainerCmd -> - createContainerCmd.getHostConfig() - .withPortBindings(PortBinding.parse("9090:9090"), PortBinding.parse("12345:12345"))); - - @Before - public void setUp() { - String host = pravega.getHost(); - int port = pravega.getFirstMappedPort(); - controllerURI = URI.create(String.format("tcp://%s:%d", host, port)); - streamManager = StreamManager.create(controllerURI); - } - - @Test - public void startTest() { - PravegaClient pravegaClient = getNewPravegaClient(); - pravegaClient.start(); - assertTrue(streamManager.checkScopeExists(config.getScope())); - } - - @Test - public void shutdownTest() { - PravegaClient pravegaClient = getNewPravegaClient(); - pravegaClient.start(); - pravegaClient.publish("test1", createCloudEvent()); - pravegaClient.publish("test2", createCloudEvent()); - pravegaClient.publish("test3", createCloudEvent()); - - pravegaClient.shutdown(); - assertTrue(pravegaClient.getSubscribeTaskMap().isEmpty()); - assertTrue(pravegaClient.getWriterMap().isEmpty()); - } - - @Test - public void publishTest() { - PravegaClient pravegaClient = getNewPravegaClient(); - pravegaClient.start(); - pravegaClient.publish("test1", createCloudEvent()); - pravegaClient.publish("test2", createCloudEvent()); - assertTrue(streamManager.checkStreamExists(config.getScope(), "test1")); - assertTrue(streamManager.checkStreamExists(config.getScope(), "test2")); - } - - @Test - public void subscribeTest() { - PravegaClient pravegaClient = getNewPravegaClient(); - pravegaClient.start(); - pravegaClient.subscribe("test1", false, "consumerGroup", "instanceName", new EventListener() { - @Override - public void consume(CloudEvent cloudEvent, AsyncConsumeContext context) { - // do nothing - } - }); - assertNotNull(pravegaClient.getReaderGroupManager().getReaderGroup("test1-consumerGroup")); - assertTrue(pravegaClient.getSubscribeTaskMap().containsKey("test1")); - } - - @Test - public void unsubscribeTest() { - PravegaClient pravegaClient = getNewPravegaClient(); - pravegaClient.unsubscribe("test1", false, "consumerGroup"); - - pravegaClient.start(); - pravegaClient.subscribe("test1", false, "consumerGroup", "instanceName", new EventListener() { - @Override - public void consume(CloudEvent cloudEvent, AsyncConsumeContext context) { - // do nothing - } - }); - pravegaClient.unsubscribe("test1", false, "consumerGroup"); - - assertFalse(pravegaClient.getSubscribeTaskMap().containsKey("test1")); - try { - pravegaClient.getReaderGroupManager().getReaderGroup("test1-consumerGroup"); - } catch (Exception e) { - assertTrue(e instanceof ReaderGroupNotFoundException); - return; - } - fail(); - } - - @Test - public void checkTopicExistTest() { - PravegaClient pravegaClient = getNewPravegaClient(); - pravegaClient.start(); - assertFalse(pravegaClient.checkTopicExist("test1")); - - pravegaClient.publish("test1", createCloudEvent()); - assertTrue(pravegaClient.checkTopicExist("test1")); - } - - public PravegaClient getNewPravegaClient() { - ConfigService configService = ConfigService.getInstance(); - - this.config = configService.buildConfigInstance(PravegaStorageConfig.class); - this.config.setControllerURI(controllerURI); - return PravegaClient.getNewInstance(this.config); - } - - private CloudEvent createCloudEvent() { - String data = "{\"headers\":{\"content-length\":\"36\",\"Accept\":\"*/*\",\"ip\":\"127.0.0.1:51226\",\"User-Agent\":\"curl/7.83.1\"," - + "\"Host\":\"127.0.0.1:10105\",\"source\":\"127.0.0.1:51226\",\"Content-Type\":\"application/json\"}," - + "\"path\":\"/eventmesh/publish/TEST-TOPIC-HTTP-ASYNC\",\"method\":\"POST\",\"body\":{\"pass\":\"12345678\",\"name\":\"admin\"}}"; - return CloudEventBuilder.v1() - .withId("c61039e1-7884-4d7f-b72f-6c61160a64fc") - .withSource(URI.create("source:127.0.0.1:51226")) - .withType("http_request") - .withDataContentType("application/json") - .withSubject("TEST-TOPIC-HTTP-ASYNC") - .withData(data.getBytes(StandardCharsets.UTF_8)) - .withExtension("reqeventmesh2mqtimestamp", "1659342713460") - .withExtension("ip", "127.0.0.1:51226") - .withExtension("idc", "idc") - .withExtension("protocoldesc", "http") - .withExtension("pid", 2376) - .withExtension("env", "env") - .withExtension("sys", 1234) - .withExtension("ttl", 4000) - .withExtension("producergroup", "em-http-producer") - .withExtension("consumergroup", "em-http-consumer") - .withExtension("passwd", "pass") - .withExtension("bizseqno", "249695004068274968410952665702") - .withExtension("protocoltype", "http") - .withExtension("msgtype", "persistent") - .withExtension("uniqueid", "866012286651006371403062105469") - .withExtension("username", "eventmesh") - .withExtension("reqc2eventmeshtimestamp", "1659342713460") - .build(); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/test/java/org/apache/eventmesh/storage/pravega/config/PravegaStorageConfigTest.java b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/test/java/org/apache/eventmesh/storage/pravega/config/PravegaStorageConfigTest.java deleted file mode 100644 index e7b24e89d3..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/test/java/org/apache/eventmesh/storage/pravega/config/PravegaStorageConfigTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.pravega.config; - -import org.apache.eventmesh.api.factory.StoragePluginFactory; -import org.apache.eventmesh.storage.pravega.PravegaConsumerImpl; -import org.apache.eventmesh.storage.pravega.PravegaProducerImpl; - -import java.net.URI; - -import org.junit.Assert; -import org.junit.Test; - -public class PravegaStorageConfigTest { - - @Test - public void getConfigWhenPravegaConsumerInit() { - PravegaConsumerImpl consumer = - (PravegaConsumerImpl) StoragePluginFactory.getMeshMQPushConsumer("pravega"); - - PravegaStorageConfig config = consumer.getClientConfiguration(); - assertConfig(config); - } - - @Test - public void getConfigWhenPravegaProducerInit() { - PravegaProducerImpl producer = - (PravegaProducerImpl) StoragePluginFactory.getMeshMQProducer("pravega"); - - PravegaStorageConfig config = producer.getClientConfiguration(); - assertConfig(config); - } - - private void assertConfig(PravegaStorageConfig config) { - Assert.assertEquals(URI.create("tcp://127.0.0.1:816"), config.getControllerURI()); - Assert.assertEquals("scope-success!!!", config.getScope()); - Assert.assertTrue(config.isAuthEnabled()); - Assert.assertEquals("username-success!!!", config.getUsername()); - Assert.assertEquals("password-success!!!", config.getPassword()); - Assert.assertTrue(config.isTlsEnable()); - Assert.assertEquals("truststore-success!!!", config.getTruststore()); - Assert.assertEquals(816, config.getClientPoolSize()); - Assert.assertEquals(1816, config.getQueueSize()); - } -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/test/resources/pravega-storage.properties b/eventmesh-storage-plugin/eventmesh-storage-pravega/src/test/resources/pravega-storage.properties deleted file mode 100644 index 5bb5e54907..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-pravega/src/test/resources/pravega-storage.properties +++ /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. -# -#######################pravega-client################## -eventMesh.server.pravega.controller.uri=tcp://127.0.0.1:816 -eventMesh.server.pravega.scope=scope-success!!! -eventMesh.server.pravega.authEnabled=false -eventMesh.server.pravega.username=username-success!!! -eventMesh.server.pravega.password=password-success!!! -eventMesh.server.pravega.tlsEnabled=true -eventMesh.server.pravega.truststore=truststore-success!!! -eventMesh.server.pravega.clientPool.size=816 -eventMesh.server.pravega.queue.size=1816 \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pulsar/build.gradle b/eventmesh-storage-plugin/eventmesh-storage-pulsar/build.gradle index b0df2615a5..77922e241a 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-pulsar/build.gradle +++ b/eventmesh-storage-plugin/eventmesh-storage-pulsar/build.gradle @@ -34,8 +34,6 @@ dependencies { testImplementation 'io.cloudevents:cloudevents-json-jackson' testImplementation "org.mockito:mockito-core" - testImplementation "org.powermock:powermock-module-junit4" - testImplementation "org.powermock:powermock-api-mockito2" compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/admin/PulsarAdmin.java b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/admin/PulsarAdmin.java new file mode 100644 index 0000000000..f75f655f9c --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/admin/PulsarAdmin.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.storage.pulsar.admin; + +import org.apache.eventmesh.api.admin.AbstractAdmin; +import org.apache.eventmesh.api.admin.TopicProperties; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.cloudevents.CloudEvent; + +public class PulsarAdmin extends AbstractAdmin { + + public PulsarAdmin() { + super(new AtomicBoolean(false)); + } + + @Override + public List getTopic() { + // TODO implement admin functions + return new ArrayList<>(); + } + + @Override + public void createTopic(String topicName) { + } + + @Override + public void deleteTopic(String topicName) { + } + + @Override + public void publish(CloudEvent cloudEvent) throws Exception { + } + + @Override + public void shutdown() { + } +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/admin/PulsarAdminAdaptor.java b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/admin/PulsarAdminAdaptor.java new file mode 100644 index 0000000000..e2e58c6b7e --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/admin/PulsarAdminAdaptor.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.storage.pulsar.admin; + +import org.apache.eventmesh.api.admin.Admin; +import org.apache.eventmesh.api.admin.TopicProperties; + +import java.util.List; +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +public class PulsarAdminAdaptor implements Admin { + + private final PulsarAdmin admin; + + public PulsarAdminAdaptor() { + admin = new PulsarAdmin(); + } + + @Override + public boolean isStarted() { + return admin.isStarted(); + } + + @Override + public boolean isClosed() { + return admin.isClosed(); + } + + @Override + public void start() { + admin.start(); + } + + @Override + public void shutdown() { + admin.shutdown(); + } + + @Override + public void init(Properties properties) throws Exception { + admin.init(properties); + } + + @Override + public List getTopic() throws Exception { + return admin.getTopic(); + } + + @Override + public void createTopic(String topicName) { + admin.createTopic(topicName); + } + + @Override + public void deleteTopic(String topicName) { + admin.deleteTopic(topicName); + } + + @Override + public List getEvent(String topicName, int offset, int length) throws Exception { + return admin.getEvent(topicName, offset, length); + } + + @Override + public void publish(CloudEvent cloudEvent) throws Exception { + admin.publish(cloudEvent); + } +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/client/PulsarClientWrapper.java b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/client/PulsarClientWrapper.java index 491ce01f21..a164b69e64 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/client/PulsarClientWrapper.java +++ b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/client/PulsarClientWrapper.java @@ -51,7 +51,7 @@ public class PulsarClientWrapper { private final PulsarClient pulsarClient; private final Map> producerMap = new HashMap<>(); - public PulsarClientWrapper(ClientConfiguration config, Properties properties) { + public PulsarClientWrapper(ClientConfiguration config, Properties properties) { this.config = config; String token = properties.getProperty(Constants.PRODUCER_TOKEN); try { @@ -63,19 +63,17 @@ public PulsarClientWrapper(ClientConfiguration config, Properties properties) { "Authentication Enabled in pulsar cluster, Please set authParams in pulsar-client.properties"); clientBuilder.authentication( config.getAuthPlugin(), - config.getAuthParams() - ); + config.getAuthParams()); } if (StringUtils.isNotBlank(token)) { clientBuilder.authentication( - AuthenticationFactory.token(token) - ); + AuthenticationFactory.token(token)); } this.pulsarClient = clientBuilder.build(); } catch (PulsarClientException ex) { throw new StorageRuntimeException( - String.format("Failed to connect pulsar cluster %s with exception: %s", config.getServiceAddr(), ex.getMessage())); + String.format("Failed to connect pulsar cluster %s with exception: %s", config.getServiceAddr(), ex.getMessage())); } } @@ -89,7 +87,7 @@ private Producer createProducer(String topic) { .create(); } catch (PulsarClientException ex) { throw new StorageRuntimeException( - String.format("Failed to create pulsar producer for %s with exception: %s", topic, ex.getMessage())); + String.format("Failed to create pulsar producer for %s with exception: %s", topic, ex.getMessage())); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/config/ClientConfiguration.java b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/config/ClientConfiguration.java index 5dc94accc4..855faf80c8 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/config/ClientConfiguration.java +++ b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/config/ClientConfiguration.java @@ -38,9 +38,9 @@ public class ClientConfiguration { private String authParams; /* - * the full format of topic needs a prefix, but the prefix cannot be passed in the url when the topic is carried - * - * */ + * the full format of topic needs a prefix, but the prefix cannot be passed in the url when the topic is carried + * + */ @ConfigFiled(field = "topicPrefix") private String topicPrefix; } \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/consumer/PulsarConsumerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/consumer/PulsarConsumerImpl.java index 4fedb613de..6dbcd8d68c 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/consumer/PulsarConsumerImpl.java +++ b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/consumer/PulsarConsumerImpl.java @@ -53,7 +53,6 @@ import lombok.extern.slf4j.Slf4j; - @Slf4j @Config(field = "clientConfiguration") public class PulsarConsumerImpl implements Consumer { @@ -84,19 +83,17 @@ public void init(Properties properties) throws Exception { "Authentication Enabled in pulsar cluster, Please set authParams in pulsar-client.properties"); clientBuilder.authentication( clientConfiguration.getAuthPlugin(), - clientConfiguration.getAuthParams() - ); + clientConfiguration.getAuthParams()); } if (StringUtils.isNotBlank(token)) { clientBuilder.authentication( - AuthenticationFactory.token(token) - ); + AuthenticationFactory.token(token)); } this.pulsarClient = clientBuilder.build(); } catch (Exception ex) { throw new StorageRuntimeException( - String.format("Failed to connect pulsar with exception: %s", ex.getMessage())); + String.format("Failed to connect pulsar with exception: %s", ex.getMessage())); } } @@ -114,6 +111,7 @@ public void subscribe(String topic) throws Exception { } EventMeshAsyncConsumeContext consumeContext = new EventMeshAsyncConsumeContext() { + @Override public void commit(EventMeshAction action) { log.debug("message action: {} for topic: {}", action.name(), subTopic); @@ -132,7 +130,7 @@ public void commit(EventMeshAction action) { .messageListener( (MessageListener) (ackConsumer, msg) -> { EventFormat eventFormat = Objects.requireNonNull( - EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE)); + EventFormatProvider.getInstance().resolveFormat(JsonFormat.CONTENT_TYPE)); CloudEvent cloudEvent = eventFormat.deserialize(msg.getData()); eventListener.consume(cloudEvent, consumeContext); try { @@ -143,7 +141,8 @@ public void commit(EventMeshAction action) { } catch (EventDeserializationException ex) { log.warn("The Message isn't json format, with exception:{}", ex.getMessage()); } - }).subscribe(); + }) + .subscribe(); consumerMap.putIfAbsent(consumerKey, consumer); diff --git a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/producer/AbstractProducer.java b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/producer/AbstractProducer.java index 2f3aa126d4..de3a4c5b9c 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/producer/AbstractProducer.java +++ b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/java/org/apache/eventmesh/storage/pulsar/producer/AbstractProducer.java @@ -22,7 +22,6 @@ import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; - import io.cloudevents.CloudEvent; public abstract class AbstractProducer { diff --git a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin new file mode 100644 index 0000000000..7c43228c45 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin @@ -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. + +pulsar=org.apache.eventmesh.storage.pulsar.admin.PulsarAdminAdaptor \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/test/java/org/apache/eventmesh/storage/pulsar/config/ClientConfigurationTest.java b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/test/java/org/apache/eventmesh/storage/pulsar/config/ClientConfigurationTest.java index 712c02410b..2f32715166 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/test/java/org/apache/eventmesh/storage/pulsar/config/ClientConfigurationTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-pulsar/src/test/java/org/apache/eventmesh/storage/pulsar/config/ClientConfigurationTest.java @@ -21,8 +21,8 @@ import org.apache.eventmesh.storage.pulsar.consumer.PulsarConsumerImpl; import org.apache.eventmesh.storage.pulsar.producer.PulsarProducerImpl; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class ClientConfigurationTest { @@ -43,8 +43,8 @@ public void getConfigWhenPulsarProducerInit() { } private void assertConfig(ClientConfiguration config) { - Assert.assertEquals("127.0.0.1:6650", config.getServiceAddr()); - Assert.assertEquals("authPlugin-success!!!", config.getAuthPlugin()); - Assert.assertEquals("authParams-success!!!", config.getAuthParams()); + Assertions.assertEquals("127.0.0.1:6650", config.getServiceAddr()); + Assertions.assertEquals("authPlugin-success!!!", config.getAuthPlugin()); + Assertions.assertEquals("authParams-success!!!", config.getAuthParams()); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/build.gradle b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/build.gradle index c20141250b..69b4f75bac 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/build.gradle +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/build.gradle @@ -35,8 +35,6 @@ dependencies { testImplementation 'io.cloudevents:cloudevents-json-jackson' testImplementation "org.mockito:mockito-core" - testImplementation "org.powermock:powermock-module-junit4" - testImplementation "org.powermock:powermock-api-mockito2" compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/README.md b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/README.md new file mode 100644 index 0000000000..fe90c2163e --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/README.md @@ -0,0 +1,26 @@ +## Dashboard + +To enable eventmesh-dashboard admin UI for RabbitMQ, you need to add plugin rabbitmq_management. + +```bash +rabbitmq-plugins enable rabbitmq_management +``` + +## RabbitMQ Management + +The RabbitMQ management UI can be accessed using a Web browser at `http://{node-hostname}:15672/`. + +Users must be [granted permissions](https://www.rabbitmq.com/management.html#permissions) for management UI access. + +The following example creates a user with complete access to the management UI/HTTP API (as in, all virtual hosts and management features): + +```bash +# create a user +rabbitmqctl add_user full_access s3crEt +# tag the user with "administrator" for full management UI and HTTP API access +rabbitmqctl set_user_tags full_access administrator +``` + +eventmesh-dashboard does not support authenticating with OAuth 2 currently. If you are using OAuth 2 to authenticate, you should keep `management.disable_basic_auth` configuration at default value `false` to support HTTP basic authentication. + +> More information for developers to provide admin functions: https://github.com/apache/eventmesh/pull/4395 diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/admin/RabbitMQAdmin.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/admin/RabbitMQAdmin.java new file mode 100644 index 0000000000..902853bed9 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/admin/RabbitMQAdmin.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.storage.rabbitmq.admin; + +import org.apache.eventmesh.api.admin.AbstractAdmin; +import org.apache.eventmesh.api.admin.TopicProperties; +import org.apache.eventmesh.storage.rabbitmq.config.ConfigurationHolder; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.cloudevents.CloudEvent; + +public class RabbitMQAdmin extends AbstractAdmin { + + private ConfigurationHolder configurationHolder; + + private String mgmtHost; + + private int mgmtPort; + + private String mgmtProtocol; + + public RabbitMQAdmin() { + super(new AtomicBoolean(false)); + } + + public void init() throws Exception { + this.mgmtHost = configurationHolder.getHost(); + this.mgmtPort = configurationHolder.getMgmtPort(); + this.mgmtProtocol = configurationHolder.getMgmtProtocol(); + } + + @Override + public List getTopic() { + // Utilizing the RabbitMQ Management HTTP API is a favorable approach to list queues and historical message counts. + // To display topics, it would be necessary to retrieve the topic name from each message and use it to declare a corresponding queue. + return new ArrayList<>(); + } + + @Override + public void createTopic(String topicName) { + } + + @Override + public void deleteTopic(String topicName) { + } + + @Override + public void publish(CloudEvent cloudEvent) throws Exception { + } + + @Override + public void shutdown() { + } +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/admin/RabbitMQAdminAdaptor.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/admin/RabbitMQAdminAdaptor.java new file mode 100644 index 0000000000..e2792f9511 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/admin/RabbitMQAdminAdaptor.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.storage.rabbitmq.admin; + +import org.apache.eventmesh.api.admin.Admin; +import org.apache.eventmesh.api.admin.TopicProperties; + +import java.util.List; +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +public class RabbitMQAdminAdaptor implements Admin { + + private final RabbitMQAdmin admin; + + public RabbitMQAdminAdaptor() { + admin = new RabbitMQAdmin(); + } + + @Override + public boolean isStarted() { + return admin.isStarted(); + } + + @Override + public boolean isClosed() { + return admin.isClosed(); + } + + @Override + public void start() { + admin.start(); + } + + @Override + public void shutdown() { + admin.shutdown(); + } + + @Override + public void init(Properties properties) throws Exception { + admin.init(properties); + } + + @Override + public List getTopic() throws Exception { + return admin.getTopic(); + } + + @Override + public void createTopic(String topicName) { + admin.createTopic(topicName); + } + + @Override + public void deleteTopic(String topicName) { + admin.deleteTopic(topicName); + } + + @Override + public List getEvent(String topicName, int offset, int length) throws Exception { + return admin.getEvent(topicName, offset, length); + } + + @Override + public void publish(CloudEvent cloudEvent) throws Exception { + admin.publish(cloudEvent); + } +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/client/RabbitmqClient.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/client/RabbitmqClient.java index 2869a56f28..4e44c77fe3 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/client/RabbitmqClient.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/client/RabbitmqClient.java @@ -29,14 +29,12 @@ @Slf4j public class RabbitmqClient { - private final RabbitmqConnectionFactory rabbitmqConnectionFactory; public RabbitmqClient(RabbitmqConnectionFactory rabbitmqConnectionFactory) { this.rabbitmqConnectionFactory = rabbitmqConnectionFactory; } - /** * get rabbitmq connection * diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/config/ConfigurationHolder.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/config/ConfigurationHolder.java index 13ec86b325..1bd1f6dc11 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/config/ConfigurationHolder.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/config/ConfigurationHolder.java @@ -57,4 +57,10 @@ public class ConfigurationHolder { @ConfigFiled(field = "autoAck") private boolean autoAck; + + @ConfigFiled(field = "mgmt.port") + private int mgmtPort; + + @ConfigFiled(field = "mgmt.protocol") + private String mgmtProtocol; } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumer.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumer.java index 6e76d473d4..140a1f56ab 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumer.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumer.java @@ -30,7 +30,6 @@ import java.util.Properties; import java.util.concurrent.ThreadPoolExecutor; - import io.cloudevents.CloudEvent; import com.rabbitmq.client.Channel; @@ -43,7 +42,6 @@ @Slf4j public class RabbitmqConsumer implements Consumer { - private RabbitmqConnectionFactory rabbitmqConnectionFactory = new RabbitmqConnectionFactory(); private RabbitmqClient rabbitmqClient; diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumerHandler.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumerHandler.java index 5e4abaad18..1872610c71 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumerHandler.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumerHandler.java @@ -35,7 +35,6 @@ @Slf4j public class RabbitmqConsumerHandler implements Runnable { - private final Channel channel; private final ConfigurationHolder configurationHolder; private final AtomicBoolean stop = new AtomicBoolean(false); @@ -55,6 +54,7 @@ public void run() { RabbitmqCloudEvent rabbitmqCloudEvent = RabbitmqCloudEvent.getFromByteArray(response.getBody()); CloudEvent cloudEvent = rabbitmqCloudEvent.convertToCloudEvent(); final EventMeshAsyncConsumeContext consumeContext = new EventMeshAsyncConsumeContext() { + @Override public void commit(EventMeshAction action) { log.info("[RabbitmqConsumerHandler] Rabbitmq consumer context commit."); diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/producer/RabbitmqProducer.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/producer/RabbitmqProducer.java index 4b12bce761..f3963d7647 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/producer/RabbitmqProducer.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/producer/RabbitmqProducer.java @@ -118,8 +118,7 @@ public void publish(CloudEvent cloudEvent, SendCallback sendCallback) throws Exc .topic(cloudEvent.getSubject()) .messageId(cloudEvent.getId()) .exception(new StorageRuntimeException(ex)) - .build() - ); + .build()); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/utils/ByteArrayUtils.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/utils/ByteArrayUtils.java index b506eca193..a362767ca9 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/utils/ByteArrayUtils.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/java/org/apache/eventmesh/storage/rabbitmq/utils/ByteArrayUtils.java @@ -30,7 +30,7 @@ public class ByteArrayUtils { public static Optional objectToBytes(T obj) throws IOException { String s = JsonUtils.toJSONString(obj); - byte[] bytes = s.getBytes(); + byte[] bytes = s.getBytes(Constants.DEFAULT_CHARSET); return Optional.ofNullable(bytes); } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin new file mode 100644 index 0000000000..3d2bdc8116 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin @@ -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. + +rabbitmq=org.apache.eventmesh.storage.rabbitmq.admin.RabbitMQAdminAdaptor \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/resources/rabbitmq-client.properties b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/resources/rabbitmq-client.properties index db9f3a5fa8..0a282dff4e 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/resources/rabbitmq-client.properties +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/main/resources/rabbitmq-client.properties @@ -16,16 +16,21 @@ # ####################### rabbitmq server ################## -eventMesh.server.rabbitmq.host= -eventMesh.server.rabbitmq.port= -eventMesh.server.rabbitmq.username= -eventMesh.server.rabbitmq.passwd= -eventMesh.server.rabbitmq.virtualHost= +eventMesh.server.rabbitmq.host=127.0.0.1 +eventMesh.server.rabbitmq.port=5672 +eventMesh.server.rabbitmq.username=guest +eventMesh.server.rabbitmq.passwd=guest +eventMesh.server.rabbitmq.virtualHost=/ ####################### rabbitmq queue setting ################## # DIRECT, FANOUT, TOPIC, HEADERS eventMesh.server.rabbitmq.exchangeType=TOPIC -eventMesh.server.rabbitmq.exchangeName= -eventMesh.server.rabbitmq.routingKey= -eventMesh.server.rabbitmq.queueName= -eventMesh.server.rabbitmq.autoAck=true \ No newline at end of file +eventMesh.server.rabbitmq.exchangeName=eventmesh.default +eventMesh.server.rabbitmq.routingKey=# +eventMesh.server.rabbitmq.queueName=DefaultQueue +eventMesh.server.rabbitmq.autoAck=true + +####################### rabbitmq management ################## +eventMesh.server.rabbitmq.mgmt.port=15672 +# HTTP, HTTPS +eventMesh.server.rabbitmq.mgmt.protocol=HTTP \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/RabbitmqServer.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/RabbitmqServer.java index 2bca2e9472..e7fba2d3fb 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/RabbitmqServer.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/RabbitmqServer.java @@ -23,15 +23,15 @@ import java.util.Properties; -import org.junit.After; -import org.junit.Before; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; public class RabbitmqServer { protected RabbitmqConsumer rabbitmqConsumer; protected RabbitmqProducer rabbitmqProducer; - @Before + @BeforeEach public void setup() throws Exception { RabbitmqMockConnectionFactory rabbitmqMockConnectionFactory = new RabbitmqMockConnectionFactory(); @@ -47,7 +47,7 @@ public void setup() throws Exception { rabbitmqProducer.start(); } - @After + @AfterEach public void shutdown() { rabbitmqConsumer.shutdown(); rabbitmqProducer.shutdown(); diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/cloudevent/RabbitmqCloudEventTest.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/cloudevent/RabbitmqCloudEventTest.java index c5bb044056..95620bd738 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/cloudevent/RabbitmqCloudEventTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/cloudevent/RabbitmqCloudEventTest.java @@ -21,9 +21,9 @@ import java.nio.charset.StandardCharsets; import java.time.OffsetDateTime; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import io.cloudevents.CloudEvent; import io.cloudevents.core.builder.CloudEventBuilder; @@ -32,7 +32,7 @@ public class RabbitmqCloudEventTest { private CloudEvent cloudEvent; - @Before + @BeforeEach public void before() { cloudEvent = CloudEventBuilder.v1() .withId("1") @@ -49,22 +49,22 @@ public void before() { public void toByteArray() throws Exception { RabbitmqCloudEventWriter writer = new RabbitmqCloudEventWriter(); RabbitmqCloudEvent rabbitmqCloudEvent = writer.writeBinary(cloudEvent); - Assert.assertEquals("topic", cloudEvent.getSubject()); + Assertions.assertEquals("topic", cloudEvent.getSubject()); byte[] data = RabbitmqCloudEvent.toByteArray(rabbitmqCloudEvent); - Assert.assertNotNull(data); + Assertions.assertNotNull(data); } @Test public void getFromByteArray() throws Exception { RabbitmqCloudEventWriter writer = new RabbitmqCloudEventWriter(); RabbitmqCloudEvent rabbitmqCloudEvent = writer.writeBinary(cloudEvent); - Assert.assertEquals("topic", cloudEvent.getSubject()); + Assertions.assertEquals("topic", cloudEvent.getSubject()); byte[] data = RabbitmqCloudEvent.toByteArray(rabbitmqCloudEvent); - Assert.assertNotNull(data); + Assertions.assertNotNull(data); RabbitmqCloudEvent event = RabbitmqCloudEvent.getFromByteArray(data); - Assert.assertEquals("topic", event.getExtensions().get("subject")); + Assertions.assertEquals("topic", event.getExtensions().get("subject")); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/config/ConfigurationHolderTest.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/config/ConfigurationHolderTest.java index a2cf6c97d7..ac83e0b600 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/config/ConfigurationHolderTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/config/ConfigurationHolderTest.java @@ -21,8 +21,8 @@ import org.apache.eventmesh.storage.rabbitmq.consumer.RabbitmqConsumer; import org.apache.eventmesh.storage.rabbitmq.producer.RabbitmqProducer; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import com.rabbitmq.client.BuiltinExchangeType; @@ -47,16 +47,16 @@ public void getConfigWhenRabbitmqProducerInit() { } private void assertConfig(ConfigurationHolder config) { - Assert.assertEquals(config.getHost(), "127.0.0.1"); - Assert.assertEquals(config.getPort(), 5672); - Assert.assertEquals(config.getUsername(), "username-success!!!"); - Assert.assertEquals(config.getPasswd(), "passwd-success!!!"); - Assert.assertEquals(config.getVirtualHost(), "virtualHost-success!!!"); - - Assert.assertEquals(config.getExchangeType(), BuiltinExchangeType.TOPIC); - Assert.assertEquals(config.getExchangeName(), "exchangeName-success!!!"); - Assert.assertEquals(config.getRoutingKey(), "routingKey-success!!!"); - Assert.assertEquals(config.getQueueName(), "queueName-success!!!"); - Assert.assertTrue(config.isAutoAck()); + Assertions.assertEquals("127.0.0.1", config.getHost()); + Assertions.assertEquals(5672, config.getPort()); + Assertions.assertEquals("username-success!!!", config.getUsername()); + Assertions.assertEquals("passwd-success!!!", config.getPasswd()); + Assertions.assertEquals("virtualHost-success!!!", config.getVirtualHost()); + + Assertions.assertEquals(BuiltinExchangeType.TOPIC, config.getExchangeType()); + Assertions.assertEquals("exchangeName-success!!!", config.getExchangeName()); + Assertions.assertEquals("routingKey-success!!!", config.getRoutingKey()); + Assertions.assertEquals("queueName-success!!!", config.getQueueName()); + Assertions.assertTrue(config.isAutoAck()); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumerTest.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumerTest.java index 80f3cb64bc..5a4493dbb7 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumerTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/consumer/RabbitmqConsumerTest.java @@ -30,8 +30,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import io.cloudevents.CloudEvent; import io.cloudevents.core.builder.CloudEventBuilder; @@ -40,12 +40,12 @@ public class RabbitmqConsumerTest extends RabbitmqServer { @Test public void isStarted() { - Assert.assertTrue(rabbitmqConsumer.isStarted()); + Assertions.assertTrue(rabbitmqConsumer.isStarted()); } @Test public void isClosed() { - Assert.assertFalse(rabbitmqConsumer.isClosed()); + Assertions.assertFalse(rabbitmqConsumer.isClosed()); } @Test @@ -56,7 +56,7 @@ public void subscribe() throws Exception { rabbitmqConsumer.registerEventListener((cloudEvent, context) -> { downLatch.countDown(); context.commit(EventMeshAction.CommitMessage); - Assert.assertEquals(cloudEvent.getSubject(), "topic"); + Assertions.assertEquals(cloudEvent.getSubject(), "topic"); }); rabbitmqConsumer.subscribe("topic"); @@ -74,20 +74,21 @@ public void subscribe() throws Exception { .build(); rabbitmqProducer.publish(cloudEvent, new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { - Assert.assertEquals(cloudEvent.getId(), sendResult.getMessageId()); - Assert.assertEquals(cloudEvent.getSubject(), sendResult.getTopic()); + Assertions.assertEquals(cloudEvent.getId(), sendResult.getMessageId()); + Assertions.assertEquals(cloudEvent.getSubject(), sendResult.getTopic()); } @Override public void onException(OnExceptionContext context) { - Assert.assertEquals(cloudEvent.getId(), context.getMessageId()); - Assert.assertEquals(cloudEvent.getSubject(), context.getTopic()); + Assertions.assertEquals(cloudEvent.getId(), context.getMessageId()); + Assertions.assertEquals(cloudEvent.getSubject(), context.getTopic()); } }); } - Assert.assertTrue(downLatch.await(5, TimeUnit.MINUTES)); + Assertions.assertTrue(downLatch.await(5, TimeUnit.MINUTES)); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/producer/RabbitmqProducerTest.java b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/producer/RabbitmqProducerTest.java index 5e707a5deb..58012b07fe 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/producer/RabbitmqProducerTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rabbitmq/src/test/java/org/apache/eventmesh/storage/rabbitmq/producer/RabbitmqProducerTest.java @@ -30,8 +30,8 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import io.cloudevents.CloudEvent; import io.cloudevents.core.builder.CloudEventBuilder; @@ -40,12 +40,12 @@ public class RabbitmqProducerTest extends RabbitmqServer { @Test public void isStarted() { - Assert.assertTrue(rabbitmqProducer.isStarted()); + Assertions.assertTrue(rabbitmqProducer.isStarted()); } @Test public void isClosed() { - Assert.assertFalse(rabbitmqProducer.isClosed()); + Assertions.assertFalse(rabbitmqProducer.isClosed()); } @Test @@ -56,7 +56,7 @@ public void publish() throws Exception { rabbitmqConsumer.registerEventListener((cloudEvent, context) -> { downLatch.countDown(); context.commit(EventMeshAction.CommitMessage); - Assert.assertEquals(cloudEvent.getSubject(), "topic"); + Assertions.assertEquals(cloudEvent.getSubject(), "topic"); }); rabbitmqConsumer.subscribe("topic"); @@ -74,20 +74,21 @@ public void publish() throws Exception { .build(); rabbitmqProducer.publish(cloudEvent, new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { - Assert.assertEquals(cloudEvent.getId(), sendResult.getMessageId()); - Assert.assertEquals(cloudEvent.getSubject(), sendResult.getTopic()); + Assertions.assertEquals(cloudEvent.getId(), sendResult.getMessageId()); + Assertions.assertEquals(cloudEvent.getSubject(), sendResult.getTopic()); } @Override public void onException(OnExceptionContext context) { - Assert.assertEquals(cloudEvent.getId(), context.getMessageId()); - Assert.assertEquals(cloudEvent.getSubject(), context.getTopic()); + Assertions.assertEquals(cloudEvent.getId(), context.getMessageId()); + Assertions.assertEquals(cloudEvent.getSubject(), context.getTopic()); } }); } - Assert.assertTrue(downLatch.await(5, TimeUnit.MINUTES)); + Assertions.assertTrue(downLatch.await(5, TimeUnit.MINUTES)); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/admin/RedisAdmin.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/admin/RedisAdmin.java new file mode 100644 index 0000000000..3143c134b3 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/admin/RedisAdmin.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.storage.redis.admin; + +import org.apache.eventmesh.api.admin.AbstractAdmin; +import org.apache.eventmesh.api.admin.TopicProperties; +import org.apache.eventmesh.storage.redis.client.RedissonClient; + +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; + +import org.redisson.Redisson; +import org.redisson.api.RPatternTopic; +import org.redisson.api.RTopic; + +import io.cloudevents.CloudEvent; + +public class RedisAdmin extends AbstractAdmin { + + private final Redisson redisson; + + public RedisAdmin() { + super(new AtomicBoolean(false)); + redisson = RedissonClient.INSTANCE; + } + + @Override + public List getTopic() throws Exception { + // TODO: match all the topic with pattern "*" for now. + RPatternTopic patternTopic = redisson.getPatternTopic("*"); + return patternTopic.getPatternNames() + .stream() + .map(s -> new TopicProperties(s, 0)) + .collect(Collectors.toList()); + } + + @Override + public void createTopic(String topicName) throws Exception { + // Just subscribe it directly, no need to create it first. + } + + @Override + public void deleteTopic(String topicName) throws Exception { + RTopic topic = redisson.getTopic(topicName); + topic.removeAllListeners(); + } + + @Override + public void publish(CloudEvent cloudEvent) throws Exception { + RTopic topic = redisson.getTopic(cloudEvent.getSubject()); + topic.publish(cloudEvent); + } +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/admin/RedisAdminAdaptor.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/admin/RedisAdminAdaptor.java new file mode 100644 index 0000000000..7275fc70b0 --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/admin/RedisAdminAdaptor.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.storage.redis.admin; + +import org.apache.eventmesh.api.admin.Admin; +import org.apache.eventmesh.api.admin.TopicProperties; + +import java.util.List; +import java.util.Properties; + +import io.cloudevents.CloudEvent; + +public class RedisAdminAdaptor implements Admin { + + private final RedisAdmin admin; + + public RedisAdminAdaptor() { + admin = new RedisAdmin(); + } + + @Override + public boolean isStarted() { + return admin.isStarted(); + } + + @Override + public boolean isClosed() { + return admin.isClosed(); + } + + @Override + public void start() { + admin.start(); + } + + @Override + public void shutdown() { + admin.shutdown(); + } + + @Override + public void init(Properties properties) throws Exception { + admin.init(properties); + } + + @Override + public List getTopic() throws Exception { + return admin.getTopic(); + } + + @Override + public void createTopic(String topicName) throws Exception { + admin.createTopic(topicName); + } + + @Override + public void deleteTopic(String topicName) throws Exception { + admin.deleteTopic(topicName); + } + + @Override + public List getEvent(String topicName, int offset, int length) throws Exception { + return admin.getEvent(topicName, offset, length); + } + + @Override + public void publish(CloudEvent cloudEvent) throws Exception { + admin.publish(cloudEvent); + } +} \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/cloudevent/CloudEventCodec.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/cloudevent/CloudEventCodec.java index 9db3c43dc4..e05903d46f 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/cloudevent/CloudEventCodec.java +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/cloudevent/CloudEventCodec.java @@ -26,7 +26,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; - public class CloudEventCodec extends BaseCodec { private static final CloudEventCodec INSTANCE = new CloudEventCodec(); diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/consumer/RedisConsumer.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/consumer/RedisConsumer.java index 8cc33bfd03..0a14e4d2f5 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/consumer/RedisConsumer.java +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/consumer/RedisConsumer.java @@ -39,7 +39,6 @@ @Slf4j public class RedisConsumer implements Consumer { - private Redisson redisson; private EventMeshMessageListener messageListener; @@ -118,6 +117,7 @@ static class EventMeshMessageListener implements MessageListener { public void onMessage(CharSequence channel, CloudEvent msg) { final EventMeshAsyncConsumeContext consumeContext = new EventMeshAsyncConsumeContext() { + @Override public void commit(EventMeshAction action) { log.info("channel: {} consumer event: {} finish action: {}", diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/producer/RedisProducer.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/producer/RedisProducer.java index db186dbdb6..532f950b6d 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/producer/RedisProducer.java +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/java/org/apache/eventmesh/storage/redis/producer/RedisProducer.java @@ -89,8 +89,7 @@ public void publish(CloudEvent cloudEvent, SendCallback sendCallback) { .topic(cloudEvent.getSubject()) .messageId(cloudEvent.getId()) .exception(new StorageRuntimeException(throwable)) - .build() - ); + .build()); } else { SendResult sendResult = new SendResult(); sendResult.setTopic(cloudEvent.getSubject()); @@ -104,8 +103,7 @@ public void publish(CloudEvent cloudEvent, SendCallback sendCallback) { .topic(cloudEvent.getSubject()) .messageId(cloudEvent.getId()) .exception(new StorageRuntimeException(e)) - .build() - ); + .build()); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin new file mode 100644 index 0000000000..cc86b755fa --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.admin.Admin @@ -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. + +redis=org.apache.eventmesh.storage.redis.admin.RedisAdminAdaptor \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/resources/redis-client.properties b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/resources/redis-client.properties index 6222972176..e024dca8ac 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/resources/redis-client.properties +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/main/resources/redis-client.properties @@ -15,3 +15,5 @@ # limitations under the License. # +eventMesh.server.redis.serverAddress= +eventMesh.server.redis.serverPassword= diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/AbstractRedisServer.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/AbstractRedisServer.java index 82117e6dc2..7aab9737d4 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/AbstractRedisServer.java +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/AbstractRedisServer.java @@ -17,8 +17,8 @@ package org.apache.eventmesh.storage.redis; -import org.junit.AfterClass; -import org.junit.BeforeClass; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import ai.grakn.redismock.RedisServer; @@ -26,13 +26,13 @@ public abstract class AbstractRedisServer { private static RedisServer redisServer; - @BeforeClass + @BeforeAll public static void setupRedisServer() throws Exception { redisServer = RedisServer.newRedisServer(6379); redisServer.start(); } - @AfterClass + @AfterAll public static void shutdownRedisServer() { if (redisServer != null) { redisServer.stop(); diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/client/RedissonClientTest.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/client/RedissonClientTest.java index 7a051cae59..8833808fb9 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/client/RedissonClientTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/client/RedissonClientTest.java @@ -19,13 +19,13 @@ import org.apache.eventmesh.storage.redis.AbstractRedisServer; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class RedissonClientTest extends AbstractRedisServer { @Test public void testInstance() { - Assert.assertNotNull(RedissonClient.INSTANCE); + Assertions.assertNotNull(RedissonClient.INSTANCE); } -} \ No newline at end of file +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/config/RedisPropertiesTest.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/config/RedisPropertiesTest.java index 8e5c3582db..677dc406e5 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/config/RedisPropertiesTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/config/RedisPropertiesTest.java @@ -21,8 +21,8 @@ import java.util.Properties; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class RedisPropertiesTest { @@ -34,14 +34,14 @@ public void getRedisProperties() { } private void assertConfig(RedisProperties config) { - Assert.assertEquals("redis://127.0.0.1:6379", config.getServerAddress()); - Assert.assertEquals(RedisProperties.ServerType.SINGLE, config.getServerType()); - Assert.assertEquals("serverMasterName-success!!!", config.getServerMasterName()); + Assertions.assertEquals("redis://127.0.0.1:6379", config.getServerAddress()); + Assertions.assertEquals(RedisProperties.ServerType.SINGLE, config.getServerType()); + Assertions.assertEquals("serverMasterName-success!!!", config.getServerMasterName()); Properties properties = new Properties(); properties.put("threads", "2"); properties.put("nettyThreads", "2"); Properties redissonProperties = config.getRedissonProperties(); - Assert.assertEquals(properties, redissonProperties); + Assertions.assertEquals(properties, redissonProperties); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/connector/UnitTest.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/connector/UnitTest.java index 8c11c628cd..fe3aed8de1 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/connector/UnitTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/connector/UnitTest.java @@ -33,10 +33,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import io.cloudevents.CloudEvent; import io.cloudevents.core.builder.CloudEventBuilder; @@ -47,7 +47,7 @@ public class UnitTest extends AbstractRedisServer { private RedisConsumer redisConsumer; - @Before + @BeforeEach public void setup() { redisProducer = new RedisProducer(); redisProducer.init(new Properties()); @@ -58,7 +58,7 @@ public void setup() { redisConsumer.start(); } - @After + @AfterEach public void shutdown() { redisProducer.shutdown(); redisConsumer.shutdown(); @@ -71,10 +71,9 @@ public void testPubSub() throws Exception { final CountDownLatch downLatch = new CountDownLatch(expectedCount); redisConsumer.registerEventListener((cloudEvent, context) -> { - downLatch.countDown(); - context.commit(EventMeshAction.CommitMessage); - } - ); + downLatch.countDown(); + context.commit(EventMeshAction.CommitMessage); + }); final String topic = RedisConsumerTest.class.getSimpleName(); @@ -95,16 +94,14 @@ public void testPubSub() throws Exception { @Override public void onSuccess(SendResult sendResult) { - } @Override public void onException(OnExceptionContext context) { - } }); } - Assert.assertTrue(downLatch.await(5, TimeUnit.MINUTES)); + Assertions.assertTrue(downLatch.await(5, TimeUnit.MINUTES)); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/consumer/RedisConsumerTest.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/consumer/RedisConsumerTest.java index 1aae3360cd..93ca0472cc 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/consumer/RedisConsumerTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/consumer/RedisConsumerTest.java @@ -28,10 +28,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.redisson.api.RTopic; import io.cloudevents.CloudEvent; @@ -41,14 +41,14 @@ public class RedisConsumerTest extends AbstractRedisServer { private RedisConsumer redisConsumer; - @Before + @BeforeEach public void setup() { redisConsumer = new RedisConsumer(); redisConsumer.init(new Properties()); redisConsumer.start(); } - @After + @AfterEach public void shutdown() { redisConsumer.shutdown(); } @@ -60,10 +60,9 @@ public void testSubscribe() throws Exception { final CountDownLatch downLatch = new CountDownLatch(expectedCount); redisConsumer.registerEventListener((cloudEvent, context) -> { - downLatch.countDown(); - context.commit(EventMeshAction.CommitMessage); - } - ); + downLatch.countDown(); + context.commit(EventMeshAction.CommitMessage); + }); final String topic = RedisConsumerTest.class.getSimpleName(); @@ -84,7 +83,7 @@ public void testSubscribe() throws Exception { redissonTopic.publish(cloudEvent); } - Assert.assertTrue(downLatch.await(5, TimeUnit.MINUTES)); + Assertions.assertTrue(downLatch.await(5, TimeUnit.MINUTES)); redisConsumer.unsubscribe(topic); } diff --git a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/producer/RedisProducerTest.java b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/producer/RedisProducerTest.java index 5531b92261..da8ea04a52 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/producer/RedisProducerTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-redis/src/test/java/org/apache/eventmesh/storage/redis/producer/RedisProducerTest.java @@ -29,10 +29,10 @@ import java.util.UUID; import java.util.concurrent.CountDownLatch; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import io.cloudevents.CloudEvent; import io.cloudevents.core.builder.CloudEventBuilder; @@ -41,14 +41,14 @@ public class RedisProducerTest extends AbstractRedisServer { private RedisProducer redisProducer; - @Before + @BeforeEach public void setup() { redisProducer = new RedisProducer(); redisProducer.init(new Properties()); redisProducer.start(); } - @After + @AfterEach public void shutdown() { redisProducer.shutdown(); } @@ -74,15 +74,15 @@ public void testPublish() throws Exception { @Override public void onSuccess(SendResult sendResult) { downLatch.countDown(); - Assert.assertEquals(cloudEvent.getId(), sendResult.getMessageId()); - Assert.assertEquals(cloudEvent.getSubject(), sendResult.getTopic()); + Assertions.assertEquals(cloudEvent.getId(), sendResult.getMessageId()); + Assertions.assertEquals(cloudEvent.getSubject(), sendResult.getTopic()); } @Override public void onException(OnExceptionContext context) { downLatch.countDown(); - Assert.assertEquals(cloudEvent.getId(), context.getMessageId()); - Assert.assertEquals(cloudEvent.getSubject(), context.getTopic()); + Assertions.assertEquals(cloudEvent.getId(), context.getMessageId()); + Assertions.assertEquals(cloudEvent.getSubject(), context.getTopic()); } }); } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/build.gradle b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/build.gradle index 9d623da905..be30240097 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/build.gradle +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/build.gradle @@ -29,7 +29,6 @@ List rocketmq = [ "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", @@ -46,8 +45,7 @@ dependencies { testImplementation project(":eventmesh-common") testImplementation "org.mockito:mockito-core" - testImplementation "org.powermock:powermock-module-junit4" - testImplementation "org.powermock:powermock-api-mockito2" + testImplementation "org.mockito:mockito-junit-jupiter" testImplementation rocketmq diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/AbstractRmqAdmin.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/AbstractRmqAdmin.java deleted file mode 100644 index 71d5525cc3..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/AbstractRmqAdmin.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.eventmesh.storage.rocketmq.admin; - -import org.apache.eventmesh.common.config.ConfigService; -import org.apache.eventmesh.storage.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 AbstractRmqAdmin { - private DefaultMQAdminExt adminExt; - - - protected String nameServerAddr; - - protected String clusterName; - - protected DefaultMQAdminExt getAdminExt() throws Exception { - ConfigService configService = ConfigService.getInstance(); - - ClientConfiguration clientConfiguration = configService.buildConfigInstance(ClientConfiguration.class); - - nameServerAddr = clientConfiguration.getNamesrvAddr(); - clusterName = clientConfiguration.getClusterName(); - String accessKey = clientConfiguration.getAccessKey(); - String secretKey = clientConfiguration.getSecretKey(); - if (adminExt == null) { - - 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); - adminExt.start(); - } - - return adminExt; - } - - protected void shutdownExt() { - adminExt.shutdown(); - adminExt = null; - } - -} diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/RocketMQAdmin.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/RocketMQAdmin.java index 3c818be522..9175f0674c 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/RocketMQAdmin.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/RocketMQAdmin.java @@ -17,84 +17,77 @@ package org.apache.eventmesh.storage.rocketmq.admin; -import org.apache.eventmesh.api.admin.Admin; +import org.apache.eventmesh.api.admin.AbstractAdmin; import org.apache.eventmesh.api.admin.TopicProperties; +import org.apache.eventmesh.common.config.ConfigService; +import org.apache.eventmesh.storage.rocketmq.config.ClientConfiguration; import org.apache.commons.lang3.StringUtils; +import org.apache.rocketmq.acl.common.AclClientRPCHook; +import org.apache.rocketmq.acl.common.SessionCredentials; import org.apache.rocketmq.common.TopicConfig; import org.apache.rocketmq.common.admin.TopicOffset; import org.apache.rocketmq.common.admin.TopicStatsTable; import org.apache.rocketmq.common.message.MessageQueue; +import org.apache.rocketmq.remoting.RPCHook; +import org.apache.rocketmq.tools.admin.DefaultMQAdminExt; import org.apache.rocketmq.tools.command.CommandUtil; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; -import java.util.Properties; import java.util.Set; +import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; -import io.cloudevents.CloudEvent; +public class RocketMQAdmin extends AbstractAdmin { -public class RocketMQAdmin extends AbstractRmqAdmin implements Admin { + private final RPCHook rpcHook; - private final AtomicBoolean isStarted; + protected String nameServerAddr; + + protected String clusterName; private int numOfQueue = 4; private int queuePermission = 6; public RocketMQAdmin() { - isStarted = new AtomicBoolean(false); - } - - @Override - public boolean isStarted() { - return isStarted.get(); - } - - @Override - public boolean isClosed() { - return !isStarted.get(); - } - - @Override - public void start() { - isStarted.compareAndSet(false, true); - } + super(new AtomicBoolean(false)); - @Override - public void shutdown() { - isStarted.compareAndSet(true, false); - } - - @Override - public void init(Properties properties) { + ConfigService configService = ConfigService.getInstance(); + ClientConfiguration clientConfiguration = configService.buildConfigInstance(ClientConfiguration.class); + nameServerAddr = clientConfiguration.getNamesrvAddr(); + clusterName = clientConfiguration.getClusterName(); + String accessKey = clientConfiguration.getAccessKey(); + String secretKey = clientConfiguration.getSecretKey(); + rpcHook = new AclClientRPCHook(new SessionCredentials(accessKey, secretKey)); } @Override public List getTopic() throws Exception { + DefaultMQAdminExt adminExt = createMQAdminExt(); try { List result = new ArrayList<>(); - Set topicList = getAdminExt().fetchAllTopicList().getTopicList(); + adminExt.start(); + Set topicList = adminExt.fetchAllTopicList().getTopicList(); for (String topic : topicList) { long messageCount = 0; - TopicStatsTable topicStats = getAdminExt().examineTopicStats(topic); + TopicStatsTable topicStats = adminExt.examineTopicStats(topic); HashMap offsetTable = topicStats.getOffsetTable(); for (TopicOffset topicOffset : offsetTable.values()) { messageCount += topicOffset.getMaxOffset() - topicOffset.getMinOffset(); } result.add(new TopicProperties( - topic, messageCount - )); + topic, messageCount)); } result.sort(Comparator.comparing(t -> t.name)); return result; } finally { - shutdownExt(); + adminExt.shutdown(); } } @@ -103,18 +96,20 @@ public void createTopic(String topicName) throws Exception { if (StringUtils.isBlank(topicName)) { throw new Exception("Topic name can not be blank"); } + DefaultMQAdminExt adminExt = createMQAdminExt(); try { - Set brokerAddress = CommandUtil.fetchMasterAddrByClusterName(getAdminExt(), clusterName); + adminExt.start(); + Set brokerAddress = CommandUtil.fetchMasterAddrByClusterName(adminExt, clusterName); for (String masterAddress : brokerAddress) { TopicConfig topicConfig = new TopicConfig(); topicConfig.setTopicName(topicName); topicConfig.setReadQueueNums(numOfQueue); topicConfig.setWriteQueueNums(numOfQueue); topicConfig.setPerm(queuePermission); - getAdminExt().createAndUpdateTopicConfig(masterAddress, topicConfig); + adminExt.createAndUpdateTopicConfig(masterAddress, topicConfig); } } finally { - shutdownExt(); + adminExt.shutdown(); } } @@ -123,22 +118,22 @@ public void deleteTopic(String topicName) throws Exception { if (StringUtils.isBlank(topicName)) { throw new Exception("Topic name can not be blank."); } + DefaultMQAdminExt adminExt = createMQAdminExt(); try { - Set brokerAddress = CommandUtil.fetchMasterAddrByClusterName(getAdminExt(), clusterName); - getAdminExt().deleteTopicInBroker(brokerAddress, topicName); + adminExt.start(); + Set brokerAddress = CommandUtil.fetchMasterAddrByClusterName(adminExt, clusterName); + adminExt.deleteTopicInBroker(brokerAddress, topicName); } finally { - shutdownExt(); + adminExt.shutdown(); } } - @Override - public List getEvent(String topicName, int offset, int length) { - return null; + private DefaultMQAdminExt createMQAdminExt() { + DefaultMQAdminExt adminExt = new DefaultMQAdminExt(rpcHook); + String groupId = UUID.randomUUID().toString(); + adminExt.setAdminExtGroup("admin_ext_group-" + groupId); + adminExt.setNamesrvAddr(nameServerAddr); + return adminExt; } - @Override - public void publish(CloudEvent cloudEvent) { - } - - } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/RocketMQAdminAdaptor.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/RocketMQAdminAdaptor.java index 27e66d5646..5899cb803f 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/RocketMQAdminAdaptor.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/admin/RocketMQAdminAdaptor.java @@ -74,12 +74,12 @@ public void deleteTopic(String topicName) throws Exception { } @Override - public List getEvent(String topicName, int offset, int length) { + public List getEvent(String topicName, int offset, int length) throws Exception { return admin.getEvent(topicName, offset, length); } @Override - public void publish(CloudEvent cloudEvent) { + public void publish(CloudEvent cloudEvent) throws Exception { admin.publish(cloudEvent); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/RocketMQMessageFactory.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/RocketMQMessageFactory.java index b109f064e4..be9cc3fcad 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/RocketMQMessageFactory.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/RocketMQMessageFactory.java @@ -34,7 +34,6 @@ import io.cloudevents.rw.CloudEventRWException; import io.cloudevents.rw.CloudEventWriter; - @ParametersAreNonnullByDefault public final class RocketMQMessageFactory { @@ -46,7 +45,6 @@ public static MessageReader createReader(final Message message) throws CloudEven return createReader(message.getProperties(), message.getBody()); } - public static MessageReader createReader(final Map props, @Nullable final byte[] body) throws CloudEventRWException { @@ -55,11 +53,9 @@ public static MessageReader createReader(final Map props, () -> null, format -> null, () -> props.get(RocketMQHeaders.SPEC_VERSION), - sv -> new RocketMQBinaryMessageReader(sv, props, body) - ); + sv -> new RocketMQBinaryMessageReader(sv, props, body)); } - public static MessageWriter, Message> createWriter(String topic) { return new RocketMQMessageWriter<>(topic); } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/impl/RocketMQHeaders.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/impl/RocketMQHeaders.java index 781e4a306d..ec9b95dcaa 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/impl/RocketMQHeaders.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/impl/RocketMQHeaders.java @@ -34,6 +34,4 @@ public class RocketMQHeaders { public static final String SPEC_VERSION = ATTRIBUTES_TO_HEADERS.get(CloudEventV1.SPECVERSION); - } - diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/impl/RocketMQMessageWriter.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/impl/RocketMQMessageWriter.java index 520db0b034..6a7f522c13 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/impl/RocketMQMessageWriter.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/cloudevent/impl/RocketMQMessageWriter.java @@ -35,7 +35,6 @@ public final class RocketMQMessageWriter private final Message message = new Message(); - public RocketMQMessageWriter(String topic) { message.setTopic(topic); } @@ -60,7 +59,6 @@ public RocketMQMessageWriter(String topic, String keys, String tags) { } } - @Override public CloudEventContextWriter withContextAttribute(@Nonnull String name, @Nonnull String value) throws CloudEventRWException { diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/common/TopicNameHelperImpl.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/common/TopicNameHelperImpl.java new file mode 100644 index 0000000000..e0ee8843ee --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/common/TopicNameHelperImpl.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.storage.rocketmq.common; + +import org.apache.eventmesh.api.TopicNameHelper; + +import org.apache.commons.lang3.StringUtils; +import org.apache.rocketmq.common.MixAll; + +public class TopicNameHelperImpl implements TopicNameHelper { + + @Override + public boolean isRetryTopic(String retryTopic) { + if (StringUtils.isBlank(retryTopic)) { + return false; + } + return retryTopic.startsWith(MixAll.RETRY_GROUP_TOPIC_PREFIX); + } +} diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/config/ClientConfig.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/config/ClientConfig.java index d33181acac..7a31a17314 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/config/ClientConfig.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/config/ClientConfig.java @@ -17,7 +17,6 @@ package org.apache.eventmesh.storage.rocketmq.config; - import org.apache.eventmesh.storage.rocketmq.domain.NonStandardKeys; import lombok.Getter; @@ -42,7 +41,7 @@ public class ClientConfig implements NonStandardKeys { private String rmqConsumerGroup; private String rmqProducerGroup = "__OMS_PRODUCER_DEFAULT_GROUP"; private int rmqMaxRedeliveryTimes = 16; - private int rmqMessageConsumeTimeout = 15; //In minutes + private int rmqMessageConsumeTimeout = 15; // In minutes private int rmqMaxConsumeThreadNums = 64; private int rmqMinConsumeThreadNums = 20; private String rmqMessageDestination; diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/consumer/PushConsumerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/consumer/PushConsumerImpl.java index aaf8757092..d332a6c7b3 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/consumer/PushConsumerImpl.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/consumer/PushConsumerImpl.java @@ -85,7 +85,7 @@ public PushConsumerImpl(final Properties properties) { MessageModel.valueOf(clientConfig.getMessageModel())); String consumerId = OMSUtil.buildInstanceName(); - //this.rocketmqPushConsumer.setInstanceName(consumerId); + // this.rocketmqPushConsumer.setInstanceName(consumerId); this.rocketmqPushConsumer.setInstanceName(properties.getProperty("instanceName")); properties.put("CONSUMER_ID", consumerId); this.rocketmqPushConsumer.setLanguage(LanguageCode.OMS); @@ -101,7 +101,6 @@ public Properties attributes() { return properties; } - public void start() { if (this.started.compareAndSet(false, true)) { try { @@ -112,19 +111,16 @@ public void start() { } } - 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(); } @@ -149,6 +145,7 @@ public void unsubscribe(String topic) { } } + @SuppressWarnings("deprecation") public void updateOffset(List cloudEvents, AbstractContext context) { ConsumeMessageService consumeMessageService = rocketmqPushConsumer .getDefaultMQPushConsumerImpl().getConsumeMessageService(); @@ -163,7 +160,6 @@ public void updateOffset(List cloudEvents, AbstractContext context) .updateOffset(msgExtList, (EventMeshConsumeConcurrentlyContext) context); } - private class BroadCastingMessageListener extends EventMeshMessageListenerConcurrently { @Override @@ -178,7 +174,7 @@ public EventMeshConsumeConcurrentlyStatus handleMessage(MessageExt msg, msg.putUserProperty(Constants.PROPERTY_MESSAGE_STORE_TIMESTAMP, String.valueOf(msg.getStoreTimestamp())); - //for rr request/reply + // for rr request/reply CloudEvent cloudEvent = RocketMQMessageFactory.createReader(CloudEventUtils.msgConvert(msg)).toEvent(); @@ -203,6 +199,7 @@ public EventMeshConsumeConcurrentlyStatus handleMessage(MessageExt msg, contextProperties.put(NonStandardKeys.MESSAGE_CONSUME_STATUS, EventMeshConsumeConcurrentlyStatus.RECONSUME_LATER.name()); EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = new EventMeshAsyncConsumeContext() { + @Override public void commit(EventMeshAction action) { switch (action) { @@ -232,7 +229,6 @@ public void commit(EventMeshAction action) { contextProperties.getProperty(NonStandardKeys.MESSAGE_CONSUME_STATUS)); } - } private class ClusteringMessageListener extends EventMeshMessageListenerConcurrently { @@ -276,6 +272,7 @@ public EventMeshConsumeConcurrentlyStatus handleMessage(MessageExt msg, EventMeshConsumeConcurrentlyStatus.RECONSUME_LATER.name()); EventMeshAsyncConsumeContext eventMeshAsyncConsumeContext = new EventMeshAsyncConsumeContext() { + @Override public void commit(EventMeshAction action) { switch (action) { diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/patch/EventMeshMessageListenerConcurrently.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/patch/EventMeshMessageListenerConcurrently.java index af8b477969..79ec322ad3 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/patch/EventMeshMessageListenerConcurrently.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/patch/EventMeshMessageListenerConcurrently.java @@ -63,7 +63,7 @@ public ConsumeConcurrentlyStatus consumeMessage(final List msgs, log.info("handleMessage fail", e); return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } - //return status; + // return status; } public abstract EventMeshConsumeConcurrentlyStatus handleMessage(MessageExt msg, EventMeshConsumeConcurrentlyContext context); diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/AbstractProducer.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/AbstractProducer.java index 14e7837739..c42b4927c6 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/AbstractProducer.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/AbstractProducer.java @@ -45,7 +45,7 @@ public abstract class AbstractProducer { final Properties properties; final DefaultMQProducer rocketmqProducer; protected final AtomicBoolean started = new AtomicBoolean(false); - // private boolean started = false; + // private boolean started = false; private final ClientConfig clientConfig; AbstractProducer(final Properties properties) { @@ -102,36 +102,34 @@ StorageRuntimeException checkProducerException(String topic, String msgId, Throw 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); + 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 StorageRuntimeException( - String.format("Received a broker exception, Topic=%s, msgId=%s, %s", - topic, msgId, brokerException.getErrorMessage()), e); + return new StorageRuntimeException(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 StorageRuntimeException( - String.format( - "Network connection experiences failures. Topic=%s, msgId=%s, %s", - topic, msgId, connectException.getMessage()), e); + return new StorageRuntimeException(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 StorageRuntimeException( - String.format("Topic does not exist, Topic=%s, msgId=%s", - topic, msgId), e); + return new StorageRuntimeException(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); + topic, msgId), + e); } } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/ProducerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/ProducerImpl.java index fab7166f19..681eda7a30 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/ProducerImpl.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/ProducerImpl.java @@ -68,7 +68,6 @@ public void setExtFields() { super.getRocketmqProducer().setCompressMsgBodyOverHowmuch(10); } - public SendResult send(CloudEvent cloudEvent) { this.checkProducerServiceState(rocketmqProducer.getDefaultMQProducerImpl()); org.apache.rocketmq.common.message.Message msg = @@ -88,7 +87,6 @@ public SendResult send(CloudEvent cloudEvent) { } } - public void sendOneway(CloudEvent cloudEvent) { this.checkProducerServiceState(this.rocketmqProducer.getDefaultMQProducerImpl()); org.apache.rocketmq.common.message.Message msg = @@ -102,7 +100,6 @@ public void sendOneway(CloudEvent cloudEvent) { } } - public void sendAsync(CloudEvent cloudEvent, SendCallback sendCallback) { this.checkProducerServiceState(this.rocketmqProducer.getDefaultMQProducerImpl()); org.apache.rocketmq.common.message.Message msg = @@ -157,6 +154,7 @@ private Message supplySysProp(Message msg, CloudEvent cloudEvent) { 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 @@ -186,8 +184,9 @@ public void onException(Throwable e) { } private org.apache.rocketmq.client.producer.SendCallback sendCallbackConvert(final Message message, - final SendCallback sendCallback) { + final SendCallback sendCallback) { return new org.apache.rocketmq.client.producer.SendCallback() { + @Override public void onSuccess(org.apache.rocketmq.client.producer.SendResult sendResult) { sendCallback.onSuccess(CloudEventUtils.convertSendResult(sendResult)); diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/RocketMQProducerImpl.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/RocketMQProducerImpl.java index 2027a85db8..1eba8c21fd 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/RocketMQProducerImpl.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/producer/RocketMQProducerImpl.java @@ -46,7 +46,8 @@ public class RocketMQProducerImpl implements Producer { @Override public synchronized void init(Properties keyValue) { - String producerGroup = keyValue.getProperty(Constants.PRODUCER_GROUP); + String producerGroup = + keyValue.getProperty(Constants.PRODUCER_GROUP) == null ? "RMQ-producerGroup" : keyValue.getProperty(Constants.PRODUCER_GROUP); String omsNamesrv = clientConfiguration.getNamesrvAddr(); Properties properties = new Properties(); @@ -111,7 +112,6 @@ public void setExtFields() { producer.setExtFields(); } - @Override public void sendOneway(CloudEvent message) { producer.sendOneway(message); diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/utils/BeanUtils.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/utils/BeanUtils.java index fd57f7f552..d8291d5e83 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/utils/BeanUtils.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/utils/BeanUtils.java @@ -108,7 +108,7 @@ public static T populate(final Properties properties, final T obj) { try { setProperties(clazz, obj, "set" + beanFieldNameWithCapitalization, entry.getValue()); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { - //ignored... + // ignored... } } } catch (RuntimeException e) { @@ -146,4 +146,3 @@ public static void setProperties(Class clazz, Object obj, String methodName, } } } - diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/utils/CloudEventUtils.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/utils/CloudEventUtils.java index 00f6bdc708..50ccc6e93b 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/utils/CloudEventUtils.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/eventmesh/storage/rocketmq/utils/CloudEventUtils.java @@ -30,13 +30,11 @@ import java.util.function.BiConsumer; import java.util.function.Function; - import lombok.extern.slf4j.Slf4j; @Slf4j public class CloudEventUtils { - public static SendResult convertSendResult( org.apache.rocketmq.client.producer.SendResult rmqResult) { SendResult sendResult = new SendResult(); @@ -45,7 +43,6 @@ public static SendResult convertSendResult( return sendResult; } - public static Message msgConvert(MessageExt rmqMsg) { Message message = new Message(); initProperty(rmqMsg, message, MessageExt::getTopic, Message::setTopic); @@ -72,7 +69,7 @@ public static Message msgConvert(MessageExt rmqMsg) { MessageAccessor.putProperty(message, Constants.PROPERTY_MESSAGE_STORE_TIMESTAMP, String.valueOf(rmqMsg.getStoreTimestamp())); - //use in manual ack + // use in manual ack MessageAccessor.putProperty(message, Constants.PROPERTY_MESSAGE_QUEUE_ID, String.valueOf(rmqMsg.getQueueId())); MessageAccessor.putProperty(message, Constants.PROPERTY_MESSAGE_QUEUE_OFFSET, String.valueOf(rmqMsg.getQueueOffset())); @@ -99,12 +96,12 @@ public static MessageExt msgConvertExt(Message message) { rmqMessageExt.setBody(message.getBody()); } - //All destinations in RocketMQ use Topic + // All destinations in RocketMQ use Topic rmqMessageExt.setTopic(message.getTopic()); int queueId = Integer.parseInt(message.getProperty(Constants.PROPERTY_MESSAGE_QUEUE_ID)); long queueOffset = Long.parseLong(message.getProperty(Constants.PROPERTY_MESSAGE_QUEUE_OFFSET)); - //use in manual ack + // use in manual ack rmqMessageExt.setQueueId(queueId); rmqMessageExt.setQueueOffset(queueOffset); diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyService.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyService.java index 80fd263b77..f58a20ceae 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyService.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/java/org/apache/rocketmq/client/impl/consumer/ConsumeMessageConcurrentlyService.java @@ -213,7 +213,7 @@ public void submitConsumeRequest( this.submitConsumeRequestLater(consumeRequest); } } else { - for (int total = 0; total < msgs.size(); ) { + for (int total = 0; total < msgs.size();) { List msgThis = new ArrayList<>(consumeBatchSize); for (int i = 0; i < consumeBatchSize; i++, total++) { if (total < msgs.size()) { @@ -327,7 +327,6 @@ public void updateOffset(List msgs, ConsumeConcurrentlyContext conte } } - public ConsumerStatsManager getConsumerStatsManager() { return this.defaultMQPushConsumerImpl.getConsumerStatsManager(); } @@ -348,8 +347,7 @@ public boolean sendMessageBack(final MessageExt msg, final ConsumeConcurrentlyCo private void submitConsumeRequestLater( final List msgs, final ProcessQueue processQueue, - final MessageQueue messageQueue - ) { + final MessageQueue messageQueue) { this.scheduledExecutorService.schedule( () -> ConsumeMessageConcurrentlyService.this.submitConsumeRequest(msgs, processQueue, messageQueue, true), 5000, TimeUnit.MILLISECONDS); @@ -368,7 +366,7 @@ private void submitConsumeRequestLater(final ConsumeRequest consumeRequest) { success = true; break; } catch (RejectedExecutionException e) { - //ignore + // ignore } } if (!success) { @@ -432,7 +430,6 @@ public void run() { MessageAccessor.setConsumeStartTimeStamp(msg, String.valueOf(System.currentTimeMillis())); } - } status = ConsumeMessageConcurrentlyService.this.messageListener.consumeMessage(Collections.unmodifiableList(msgs), context); } catch (Throwable e) { diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.TopicNameHelper b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.TopicNameHelper new file mode 100644 index 0000000000..4670fbc91f --- /dev/null +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/main/resources/META-INF/eventmesh/org.apache.eventmesh.api.TopicNameHelper @@ -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.storage.rocketmq.common.TopicNameHelperImpl \ No newline at end of file diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/cloudevent/RocketMQMessageFactoryTest.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/cloudevent/RocketMQMessageFactoryTest.java index 1fc91ba4bf..4ecfdcfd6c 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/cloudevent/RocketMQMessageFactoryTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/cloudevent/RocketMQMessageFactoryTest.java @@ -15,16 +15,15 @@ * limitations under the License. */ - package org.apache.eventmesh.storage.rocketmq.cloudevent; import org.apache.eventmesh.storage.rocketmq.cloudevent.impl.RocketMQHeaders; import org.apache.rocketmq.common.message.Message; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import io.cloudevents.SpecVersion; @@ -32,7 +31,7 @@ public class RocketMQMessageFactoryTest { private Message message; - @Before + @BeforeEach public void setUp() { message = new Message(); message.putUserProperty(RocketMQHeaders.SPEC_VERSION, SpecVersion.V03.toString()); @@ -41,6 +40,6 @@ public void setUp() { @Test public void testCreateReader() { - Assert.assertNotNull(RocketMQMessageFactory.createReader(message)); + Assertions.assertNotNull(RocketMQMessageFactory.createReader(message)); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/config/ClientConfigurationTest.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/config/ClientConfigurationTest.java index 3088db355f..3ec41e1419 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/config/ClientConfigurationTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/config/ClientConfigurationTest.java @@ -21,8 +21,8 @@ import org.apache.eventmesh.storage.rocketmq.consumer.RocketMQConsumerImpl; import org.apache.eventmesh.storage.rocketmq.producer.RocketMQProducerImpl; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class ClientConfigurationTest { @@ -43,21 +43,21 @@ public void getConfigWhenRocketMQProducerInit() { } private void assertConfig(ClientConfiguration config) { - Assert.assertEquals("127.0.0.1:9876;127.0.0.1:9876", config.getNamesrvAddr()); - Assert.assertEquals("username-succeed!!!", config.getClientUserName()); - Assert.assertEquals("password-succeed!!!", config.getClientPass()); - Assert.assertEquals(Integer.valueOf(1816), config.getConsumeThreadMin()); - Assert.assertEquals(Integer.valueOf(2816), config.getConsumeThreadMax()); - Assert.assertEquals(Integer.valueOf(3816), config.getConsumeQueueSize()); - Assert.assertEquals(Integer.valueOf(4816), config.getPullBatchSize()); - Assert.assertEquals(Integer.valueOf(5816), config.getAckWindow()); - Assert.assertEquals(Integer.valueOf(6816), config.getPubWindow()); - Assert.assertEquals(7816, config.getConsumeTimeout()); - Assert.assertEquals(Integer.valueOf(8816), config.getPollNameServerInterval()); - Assert.assertEquals(Integer.valueOf(9816), config.getHeartbeatBrokerInterval()); - Assert.assertEquals(Integer.valueOf(11816), config.getRebalanceInterval()); - Assert.assertEquals("cluster-succeed!!!", config.getClusterName()); - Assert.assertEquals("accessKey-succeed!!!", config.getAccessKey()); - Assert.assertEquals("secretKey-succeed!!!", config.getSecretKey()); + Assertions.assertEquals("127.0.0.1:9876;127.0.0.1:9876", config.getNamesrvAddr()); + Assertions.assertEquals("username-succeed!!!", config.getClientUserName()); + Assertions.assertEquals("password-succeed!!!", config.getClientPass()); + Assertions.assertEquals(Integer.valueOf(1816), config.getConsumeThreadMin()); + Assertions.assertEquals(Integer.valueOf(2816), config.getConsumeThreadMax()); + Assertions.assertEquals(Integer.valueOf(3816), config.getConsumeQueueSize()); + Assertions.assertEquals(Integer.valueOf(4816), config.getPullBatchSize()); + Assertions.assertEquals(Integer.valueOf(5816), config.getAckWindow()); + Assertions.assertEquals(Integer.valueOf(6816), config.getPubWindow()); + Assertions.assertEquals(7816, config.getConsumeTimeout()); + Assertions.assertEquals(Integer.valueOf(8816), config.getPollNameServerInterval()); + Assertions.assertEquals(Integer.valueOf(9816), config.getHeartbeatBrokerInterval()); + Assertions.assertEquals(Integer.valueOf(11816), config.getRebalanceInterval()); + Assertions.assertEquals("cluster-succeed!!!", config.getClusterName()); + Assertions.assertEquals("accessKey-succeed!!!", config.getAccessKey()); + Assertions.assertEquals("secretKey-succeed!!!", config.getSecretKey()); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/consumer/PushConsumerImplTest.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/consumer/PushConsumerImplTest.java index 3360a9d568..19e40f2c00 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/consumer/PushConsumerImplTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/consumer/PushConsumerImplTest.java @@ -27,15 +27,15 @@ 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.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class PushConsumerImplTest { private PushConsumerImpl consumer; @@ -43,31 +43,31 @@ public class PushConsumerImplTest { @Mock private DefaultMQPushConsumer rocketmqPushConsumer; - @Before + @BeforeEach public void before() throws Exception { Properties consumerProp = new Properties(); - //consumerProp.setProperty(OMSBuiltinKeys.DRIVER_IMPL, - // "org.apache.eventmesh.connector.rocketmq.MessagingAccessPointImpl"); + // 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); + // 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(); + // 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 + field.set(consumer, rocketmqPushConsumer); // Replace Mockito.when(rocketmqPushConsumer.getMessageListener()).thenReturn(innerConsumer.getMessageListener()); consumer.start(); } - @After + @AfterEach public void after() throws Exception { Mockito.verify(rocketmqPushConsumer).getMessageListener(); consumer.shutdown(); @@ -86,6 +86,5 @@ public void testConsumeMessage() { ((MessageListenerConcurrently) rocketmqPushConsumer .getMessageListener()).consumeMessage(Collections.singletonList(consumedMsg), null); - } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/producer/DefaultProducerImplTest.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/producer/DefaultProducerImplTest.java index ea3efaf4d0..8c93906d43 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/producer/DefaultProducerImplTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/producer/DefaultProducerImplTest.java @@ -17,40 +17,40 @@ package org.apache.eventmesh.storage.rocketmq.producer; - -import org.junit.After; -import org.junit.Before; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; public class DefaultProducerImplTest { - @Before + @BeforeEach public void before() { } - - @After + @AfterEach public void after() { - //TBD:Remove topic + // 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"); - // } - //} + /** + * @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-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/producer/ProducerImplTest.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/producer/ProducerImplTest.java index 843669ccca..5d7d01b955 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/producer/ProducerImplTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/producer/ProducerImplTest.java @@ -18,7 +18,6 @@ package org.apache.eventmesh.storage.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.StorageRuntimeException; @@ -39,18 +38,19 @@ 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.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import io.cloudevents.CloudEvent; import io.cloudevents.core.builder.CloudEventBuilder; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class ProducerImplTest { private ProducerImpl producer; @@ -58,7 +58,7 @@ public class ProducerImplTest { @Mock private DefaultMQProducer rocketmqProducer; - @Before + @BeforeEach public void before() throws NoSuchFieldException, IllegalAccessException { Properties config = new Properties(); config.setProperty("access_points", "IP1:9876,IP2:9876"); @@ -72,7 +72,7 @@ public void before() throws NoSuchFieldException, IllegalAccessException { } - @After + @AfterEach public void after() { producer.shutdown(); } @@ -117,7 +117,7 @@ public void testSend_WithException() throws InterruptedException, RemotingExcept MQClientException exception = new MQClientException("Send message to RocketMQ broker failed.", new Exception()); Mockito.when(rocketmqProducer.send(any(Message.class))).thenThrow(exception); - try { + StorageRuntimeException e = Assertions.assertThrows(StorageRuntimeException.class, () -> { CloudEvent cloudEvent = CloudEventBuilder.v1() .withId("id1") .withSource(URI.create("https://github.com/cloudevents/*****")) @@ -126,10 +126,8 @@ public void testSend_WithException() throws InterruptedException, RemotingExcept .withData(new byte[]{'a'}) .build(); producer.send(cloudEvent); - failBecauseExceptionWasNotThrown(StorageRuntimeException.class); - } catch (Exception e) { - assertThat(e).hasMessageContaining("Send message to RocketMQ broker failed."); - } + }); + assertThat(e).hasMessageContaining("Send message to RocketMQ broker failed."); Mockito.verify(rocketmqProducer).send(any(Message.class)); } diff --git a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/promise/DefaultPromiseTest.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/promise/DefaultPromiseTest.java deleted file mode 100644 index 49945104bf..0000000000 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/promise/DefaultPromiseTest.java +++ /dev/null @@ -1,122 +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 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-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/utils/BeanUtilsTest.java b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/utils/BeanUtilsTest.java index 3b595d1a8b..e949086ec4 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/utils/BeanUtilsTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-rocketmq/src/test/java/org/apache/eventmesh/storage/rocketmq/utils/BeanUtilsTest.java @@ -22,9 +22,9 @@ import java.util.Properties; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class BeanUtilsTest { @@ -69,7 +69,7 @@ public CustomizedConfig() { } } - @Before + @BeforeEach public void before() { properties.put(NonStandardKeys.MAX_REDELIVERY_TIMES, 120); properties.put(CustomizedConfig.STRING_TEST, "kaka"); @@ -84,12 +84,12 @@ public void before() { public void testPopulate() { CustomizedConfig config = BeanUtils.populate(properties, CustomizedConfig.class); - Assert.assertEquals(120, config.getRmqMaxRedeliveryTimes()); - Assert.assertEquals("kaka", config.getStringTest()); - Assert.assertEquals("Default_Consumer_Group", config.getRmqConsumerGroup()); - Assert.assertEquals(101, config.getRmqMessageConsumeTimeout()); - Assert.assertEquals(1234567890L, config.getLongTest()); - Assert.assertEquals(10.234, config.getDoubleTest(), 0.000001); + Assertions.assertEquals(120, config.getRmqMaxRedeliveryTimes()); + Assertions.assertEquals("kaka", config.getStringTest()); + Assertions.assertEquals("Default_Consumer_Group", config.getRmqConsumerGroup()); + Assertions.assertEquals(101, config.getRmqMessageConsumeTimeout()); + Assertions.assertEquals(1234567890L, config.getLongTest()); + Assertions.assertEquals(10.234, config.getDoubleTest(), 0.000001); } @Test @@ -97,16 +97,16 @@ public void testPopulate_ExistObj() { CustomizedConfig config = new CustomizedConfig(); config.setConsumerId("NewConsumerId"); - Assert.assertEquals("NewConsumerId", config.getConsumerId()); + Assertions.assertEquals("NewConsumerId", config.getConsumerId()); BeanUtils.populate(properties, config); - Assert.assertEquals(120, config.getRmqMaxRedeliveryTimes()); - Assert.assertEquals("kaka", config.getStringTest()); - Assert.assertEquals("Default_Consumer_Group", config.getRmqConsumerGroup()); - Assert.assertEquals(101, config.getRmqMessageConsumeTimeout()); - Assert.assertEquals(1234567890L, config.getLongTest()); - Assert.assertEquals(10.234, config.getDoubleTest(), 0.000001); + Assertions.assertEquals(120, config.getRmqMaxRedeliveryTimes()); + Assertions.assertEquals("kaka", config.getStringTest()); + Assertions.assertEquals("Default_Consumer_Group", config.getRmqConsumerGroup()); + Assertions.assertEquals(101, config.getRmqMessageConsumeTimeout()); + Assertions.assertEquals(1234567890L, config.getLongTest()); + Assertions.assertEquals(10.234, config.getDoubleTest(), 0.000001); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/build.gradle b/eventmesh-storage-plugin/eventmesh-storage-standalone/build.gradle index d66ed0b920..a8b1827aa7 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/build.gradle +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/build.gradle @@ -22,6 +22,6 @@ dependencies { compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' - testImplementation "org.mockito:mockito-core" testImplementation "org.mockito:mockito-inline" + testImplementation "org.mockito:mockito-junit-jupiter" } diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/admin/StandaloneAdmin.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/admin/StandaloneAdmin.java index fcaf3a972c..7f5ab2da67 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/admin/StandaloneAdmin.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/admin/StandaloneAdmin.java @@ -17,7 +17,7 @@ package org.apache.eventmesh.storage.standalone.admin; -import org.apache.eventmesh.api.admin.Admin; +import org.apache.eventmesh.api.admin.AbstractAdmin; import org.apache.eventmesh.api.admin.TopicProperties; import org.apache.eventmesh.storage.standalone.broker.MessageQueue; import org.apache.eventmesh.storage.standalone.broker.StandaloneBroker; @@ -26,45 +26,18 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import io.cloudevents.CloudEvent; -public class StandaloneAdmin implements Admin { +public class StandaloneAdmin extends AbstractAdmin { - private final AtomicBoolean isStarted; private final StandaloneBroker standaloneBroker; public StandaloneAdmin() { + super(new AtomicBoolean(false)); this.standaloneBroker = StandaloneBroker.getInstance(); - this.isStarted = new AtomicBoolean(false); - } - - @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); - } - - @Override - public void init(Properties properties) throws Exception { - } @Override @@ -76,8 +49,7 @@ public List getTopic() throws Exception { final int messageCount = messageQueue.getPutIndex() - messageQueue.getTakeIndex(); topicList.add(new TopicProperties( topicMetadata.getTopicName(), - messageCount - )); + messageCount)); }); topicList.sort(Comparator.comparing(t -> t.name)); return topicList; diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/MessageQueue.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/MessageQueue.java index dfa60f29d8..232a4ad74d 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/MessageQueue.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/MessageQueue.java @@ -24,18 +24,21 @@ import com.google.common.base.Preconditions; +import lombok.Getter; + /** * This is a block queue, can get entity by offset. The queue is a FIFO data structure. */ public class MessageQueue { - public MessageEntity[] items; + @Getter + private final MessageEntity[] items; - private int takeIndex; + private volatile int takeIndex; - private int putIndex; + private volatile int putIndex; - private int count; + private volatile int count; private final ReentrantLock lock; @@ -43,7 +46,6 @@ public class MessageQueue { private final Condition notFull; - public MessageQueue() { this(2 << 10); } @@ -59,40 +61,41 @@ public MessageQueue(int capacity) { } /** - * Insert the message at the tail of this queue, waiting for space to become available if the queue is full + * Inserts the specified MessageEntity object into the queue. * - * @param messageEntity + * @param messageEntity The MessageEntity object to be inserted into the queue. + * @throws InterruptedException if the current thread is interrupted while waiting for space to become available in the queue. */ public void put(MessageEntity messageEntity) throws InterruptedException { Preconditions.checkNotNull(messageEntity); - ReentrantLock lock = this.lock; - lock.lockInterruptibly(); + ReentrantLock reentrantLock = this.lock; + reentrantLock.lockInterruptibly(); try { while (count == items.length) { notFull.await(); } enqueue(messageEntity); } finally { - lock.unlock(); + reentrantLock.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 + * @return The MessageEntity object at the head of the queue. + * @throws InterruptedException if the current thread is interrupted while waiting for an element to become available in the queue. */ public MessageEntity take() throws InterruptedException { - ReentrantLock lock = this.lock; - lock.lockInterruptibly(); + ReentrantLock reentrantLock = this.lock; + reentrantLock.lockInterruptibly(); try { while (count == 0) { notEmpty.await(); } return dequeue(); } finally { - lock.unlock(); + reentrantLock.unlock(); } } @@ -102,12 +105,12 @@ public MessageEntity take() throws InterruptedException { * @return MessageEntity */ public MessageEntity peek() { - ReentrantLock lock = this.lock; - lock.lock(); + ReentrantLock reentrantLock = this.lock; + reentrantLock.lock(); try { return itemAt(takeIndex); } finally { - lock.unlock(); + reentrantLock.unlock(); } } @@ -126,8 +129,8 @@ public MessageEntity getHead() { * @return MessageEntity */ public MessageEntity getTail() { - ReentrantLock lock = this.lock; - lock.lock(); + ReentrantLock reentrantLock = this.lock; + reentrantLock.lock(); try { if (count == 0) { return null; @@ -138,28 +141,33 @@ public MessageEntity getTail() { } return itemAt(tailIndex); } finally { - lock.unlock(); + reentrantLock.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 + * @param offset The offset of the MessageEntity object to be retrieved. + * @return The MessageEntity object with the specified offset, or null if no such object exists in the queue. + * @throws RuntimeException if the specified offset is less than the offset of the head MessageEntity object. */ public MessageEntity getByOffset(long offset) { - ReentrantLock lock = this.lock; - lock.lock(); + ReentrantLock reentrantLock = this.lock; + reentrantLock.lock(); try { - MessageEntity head = getHead(); - if (head == null) { + if (count == 0) { return null; } + int tailIndex = putIndex - 1; + MessageEntity head = itemAt(takeIndex); if (head.getOffset() > offset) { throw new RuntimeException(String.format("The message has been deleted, offset: %s", offset)); } - MessageEntity tail = getTail(); + if (tailIndex < 0) { + tailIndex += items.length; + } + MessageEntity tail = itemAt(tailIndex); if (tail == null || tail.getOffset() < offset) { return null; } @@ -170,13 +178,16 @@ public MessageEntity getByOffset(long offset) { } return itemAt(offsetIndex); } finally { - lock.unlock(); + reentrantLock.unlock(); } } + /** + * Removes the MessageEntity object at the head of the queue. + */ public void removeHead() { - ReentrantLock lock = this.lock; - lock.lock(); + ReentrantLock reentrantLock = this.lock; + reentrantLock.lock(); try { if (count == 0) { return; @@ -187,7 +198,7 @@ public void removeHead() { } notFull.signalAll(); } finally { - lock.unlock(); + reentrantLock.unlock(); } } @@ -195,11 +206,21 @@ public int getSize() { return count; } - + /** + * Returns the MessageEntity object at the specified index. + * + * @param index The index of the MessageEntity object to be returned. + * @return The MessageEntity object at the specified index. + */ private MessageEntity itemAt(int index) { return items[index]; } + /** + * Insert the message at the tail of this queue, waiting for space to become available if the queue is full + * + * @param messageEntity The MessageEntity object to be inserted into the queue. + */ private void enqueue(MessageEntity messageEntity) { items[putIndex++] = messageEntity; if (putIndex == items.length) { @@ -209,6 +230,11 @@ private void enqueue(MessageEntity messageEntity) { notEmpty.signalAll(); } + /** + * Removes and returns the MessageEntity object at the head of the queue. + * + * @return The MessageEntity object at the head of the queue. + */ private MessageEntity dequeue() { MessageEntity item = items[takeIndex++]; if (takeIndex == items.length) { diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/model/TopicMetadata.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/model/TopicMetadata.java index 591ac9c3b0..fd8ed6c7bb 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/model/TopicMetadata.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/model/TopicMetadata.java @@ -25,7 +25,9 @@ */ public class TopicMetadata implements Serializable { - private String topicName; + private static final long serialVersionUID = -9011507202771676415L; + + private final String topicName; public TopicMetadata(String topicName) { this.topicName = topicName; diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/task/HistoryMessageClear.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/task/HistoryMessageClear.java index a2ae1c3a8b..ca43729853 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/task/HistoryMessageClear.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/task/HistoryMessageClear.java @@ -17,8 +17,6 @@ package org.apache.eventmesh.storage.standalone.broker.task; - - import org.apache.eventmesh.storage.standalone.broker.MessageQueue; import org.apache.eventmesh.storage.standalone.broker.model.MessageEntity; import org.apache.eventmesh.storage.standalone.broker.model.TopicMetadata; diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/task/Subscribe.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/task/Subscribe.java index 09e90259df..8316270adf 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/task/Subscribe.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/broker/task/Subscribe.java @@ -68,6 +68,7 @@ public void subscribe() { CloudEvent message = standaloneBroker.getMessage(topicName, offset.get()); if (message != null) { EventMeshAsyncConsumeContext consumeContext = new EventMeshAsyncConsumeContext() { + @Override public void commit(EventMeshAction action) { switch (action) { diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/consumer/StandaloneConsumer.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/consumer/StandaloneConsumer.java index 0413b5844b..9eb753e3fa 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/consumer/StandaloneConsumer.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/main/java/org/apache/eventmesh/storage/standalone/consumer/StandaloneConsumer.java @@ -54,8 +54,7 @@ public StandaloneConsumer(Properties properties) { this.consumeExecutorService = ThreadPoolFactory.createThreadPoolExecutor( Runtime.getRuntime().availableProcessors() * 2, Runtime.getRuntime().availableProcessors() * 2, - "StandaloneConsumerThread" - ); + "StandaloneConsumerThread"); } @Override @@ -88,8 +87,7 @@ public void init(Properties keyValue) throws Exception { @Override public void updateOffset(List cloudEvents, AbstractContext context) { cloudEvents.forEach(cloudEvent -> standaloneBroker.updateOffset( - new TopicMetadata(cloudEvent.getSubject()), Objects.requireNonNull((Long) cloudEvent.getExtension("offset"))) - ); + new TopicMetadata(cloudEvent.getSubject()), Objects.requireNonNull((Long) cloudEvent.getExtension("offset")))); } diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/TestUtils.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/TestUtils.java index 955e913819..7e9da6a2be 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/TestUtils.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/TestUtils.java @@ -71,8 +71,7 @@ public static MessageEntity createDefaultMessageEntity() { new TopicMetadata(TEST_TOPIC), createDefaultCloudEvent(), OFF_SET, - System.currentTimeMillis() - ); + System.currentTimeMillis()); } public static MessageEntity createMessageEntity(TopicMetadata topicMetadata, CloudEvent cloudEvent, long offSet, long currentTimeMillis) { @@ -80,7 +79,6 @@ public static MessageEntity createMessageEntity(TopicMetadata topicMetadata, Clo topicMetadata, cloudEvent, offSet, - currentTimeMillis - ); + currentTimeMillis); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/admin/StandaloneAdminTest.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/admin/StandaloneAdminTest.java index 9e271505af..557737092a 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/admin/StandaloneAdminTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/admin/StandaloneAdminTest.java @@ -31,18 +31,21 @@ import java.util.List; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; import io.cloudevents.CloudEvent; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) public class StandaloneAdminTest { @Mock @@ -50,7 +53,7 @@ public class StandaloneAdminTest { private StandaloneAdmin standaloneAdmin; - @Before + @BeforeEach public void setUp() { initStaticInstance(); } @@ -58,19 +61,19 @@ public void setUp() { @Test public void testIsStarted() { standaloneAdmin.start(); - Assert.assertTrue(standaloneAdmin.isStarted()); + Assertions.assertTrue(standaloneAdmin.isStarted()); } @Test public void testIsClosed() { standaloneAdmin.shutdown(); - Assert.assertTrue(standaloneAdmin.isClosed()); + Assertions.assertTrue(standaloneAdmin.isClosed()); } @Test public void testGetTopic() throws Exception { - Assert.assertNotNull(standaloneAdmin.getTopic()); - Assert.assertFalse(standaloneAdmin.getTopic().isEmpty()); + Assertions.assertNotNull(standaloneAdmin.getTopic()); + Assertions.assertFalse(standaloneAdmin.getTopic().isEmpty()); } @Test @@ -90,15 +93,15 @@ public void testGetEvent() throws Exception { Mockito.when(standaloneBroker.checkTopicExist(TEST_TOPIC)).thenReturn(TOPIC_EXISTS); Mockito.when(standaloneBroker.getMessage(TEST_TOPIC, OFF_SET)).thenReturn(createDefaultCloudEvent()); List events = standaloneAdmin.getEvent(TEST_TOPIC, OFF_SET, LENGTH); - Assert.assertNotNull(events); - Assert.assertFalse(events.isEmpty()); + Assertions.assertNotNull(events); + Assertions.assertFalse(events.isEmpty()); } @Test public void testGetEvent_throwException() { Mockito.when(standaloneBroker.checkTopicExist(TEST_TOPIC)).thenReturn(TOPIC_DO_NOT_EXISTS); - Exception exception = Assert.assertThrows(Exception.class, () -> standaloneAdmin.getEvent(TEST_TOPIC, OFF_SET, LENGTH)); - Assert.assertEquals("The topic name doesn't exist in the message queue", exception.getMessage()); + Exception exception = Assertions.assertThrows(Exception.class, () -> standaloneAdmin.getEvent(TEST_TOPIC, OFF_SET, LENGTH)); + Assertions.assertEquals("The topic name doesn't exist in the message queue", exception.getMessage()); } @Test diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/MessageQueueTest.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/MessageQueueTest.java index c6ef39a599..1dc6a39479 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/MessageQueueTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/MessageQueueTest.java @@ -24,9 +24,9 @@ import java.util.Arrays; import java.util.Objects; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class MessageQueueTest { @@ -36,79 +36,79 @@ public class MessageQueueTest { private static final int WRONG_OFFSET = 4; private MessageQueue messageQueue; - @Before + @BeforeEach public void setUp() throws InterruptedException { initMessageQueue(); } @Test public void testPut() { - Assert.assertTrue(Arrays.stream(messageQueue.items).findAny().isPresent()); + Assertions.assertTrue(Arrays.stream(messageQueue.getItems()).findAny().isPresent()); } @Test public void testTake() throws InterruptedException { MessageEntity takeMessage = messageQueue.take(); - Assert.assertNotNull(takeMessage); - Assert.assertTrue(Arrays.stream(messageQueue.items).findAny().isPresent()); + Assertions.assertNotNull(takeMessage); + Assertions.assertTrue(Arrays.stream(messageQueue.getItems()).findAny().isPresent()); } @Test public void testPeek() { MessageEntity peekMessage = messageQueue.peek(); - Assert.assertNotNull(peekMessage); - Assert.assertTrue(Arrays.stream(messageQueue.items).findAny().isPresent()); + Assertions.assertNotNull(peekMessage); + Assertions.assertTrue(Arrays.stream(messageQueue.getItems()).findAny().isPresent()); } @Test public void testGetHead() { MessageEntity headMessage = messageQueue.getHead(); - Assert.assertNotNull(headMessage); - Assert.assertTrue(Arrays.stream(messageQueue.items).findAny().isPresent()); + Assertions.assertNotNull(headMessage); + Assertions.assertTrue(Arrays.stream(messageQueue.getItems()).findAny().isPresent()); } @Test public void testGetTail() { MessageEntity tailMessage = messageQueue.getHead(); - Assert.assertNotNull(tailMessage); - Assert.assertTrue(Arrays.stream(messageQueue.items).findAny().isPresent()); + Assertions.assertNotNull(tailMessage); + Assertions.assertTrue(Arrays.stream(messageQueue.getItems()).findAny().isPresent()); } @Test public void testGetByOffset() { MessageEntity offSetMessageEntity = messageQueue.getByOffset(DEFAULT_OFFSET); - Assert.assertNotNull(offSetMessageEntity); - Assert.assertTrue(Arrays.stream(messageQueue.items).findAny().isPresent()); - Assert.assertEquals(DEFAULT_OFFSET, offSetMessageEntity.getOffset()); + Assertions.assertNotNull(offSetMessageEntity); + Assertions.assertTrue(Arrays.stream(messageQueue.getItems()).findAny().isPresent()); + Assertions.assertEquals(DEFAULT_OFFSET, offSetMessageEntity.getOffset()); } @Test public void testGetByOffset_whenOffSetIsWrong_thenReturnsNull() { MessageEntity offSetMessageEntity = messageQueue.getByOffset(WRONG_OFFSET); - Assert.assertNull(offSetMessageEntity); + Assertions.assertNull(offSetMessageEntity); } @Test public void testRemoveHead() { messageQueue.removeHead(); - Assert.assertTrue(Arrays.stream(messageQueue.items).anyMatch(Objects::isNull)); + Assertions.assertTrue(Arrays.stream(messageQueue.getItems()).anyMatch(Objects::isNull)); } @Test public void testGetSize() { - Assert.assertEquals(ITEMS_COUNT, messageQueue.getSize()); + Assertions.assertEquals(ITEMS_COUNT, messageQueue.getSize()); } @Test public void testGetTakeIndex() throws InterruptedException { MessageEntity takeIndexMessageEntity = messageQueue.take(); - Assert.assertNotNull(takeIndexMessageEntity); - Assert.assertEquals(1, messageQueue.getPutIndex()); + Assertions.assertNotNull(takeIndexMessageEntity); + Assertions.assertEquals(1, messageQueue.getPutIndex()); } @Test public void testGetPutIndex() { - Assert.assertEquals(1, messageQueue.getPutIndex()); + Assertions.assertEquals(1, messageQueue.getPutIndex()); } private void initMessageQueue() throws InterruptedException { diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/StandaloneBrokerTest.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/StandaloneBrokerTest.java index 7b34973763..3582f95ef5 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/StandaloneBrokerTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/StandaloneBrokerTest.java @@ -27,8 +27,8 @@ import java.util.concurrent.atomic.AtomicLong; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import io.cloudevents.CloudEvent; @@ -36,14 +36,14 @@ public class StandaloneBrokerTest { @Test public void testGetInstance() { - Assert.assertNotNull(StandaloneBroker.getInstance()); + Assertions.assertNotNull(StandaloneBroker.getInstance()); } @Test public void testCreateTopicIfAbsent() { StandaloneBroker instance = StandaloneBroker.getInstance(); Pair pair = instance.createTopicIfAbsent(TEST_TOPIC); - Assert.assertNotNull(pair); + Assertions.assertNotNull(pair); } @Test @@ -51,7 +51,7 @@ public void testPutMessage() throws InterruptedException { StandaloneBroker instance = StandaloneBroker.getInstance(); CloudEvent cloudEvent = createDefaultCloudEvent(); MessageEntity messageEntity = instance.putMessage(TEST_TOPIC, cloudEvent); - Assert.assertNotNull(messageEntity); + Assertions.assertNotNull(messageEntity); } @Test @@ -60,7 +60,7 @@ public void testTakeMessage() throws InterruptedException { CloudEvent cloudEvent = createDefaultCloudEvent(); instance.putMessage(TEST_TOPIC, cloudEvent); CloudEvent message = instance.takeMessage(TEST_TOPIC); - Assert.assertNotNull(message); + Assertions.assertNotNull(message); } @Test @@ -69,7 +69,7 @@ public void testGetMessage() throws InterruptedException { CloudEvent cloudEvent = createDefaultCloudEvent(); instance.putMessage(TEST_TOPIC, cloudEvent); CloudEvent cloudEventResult = instance.getMessage(TEST_TOPIC); - Assert.assertNotNull(cloudEventResult); + Assertions.assertNotNull(cloudEventResult); } @Test @@ -78,7 +78,7 @@ public void testMessageWithOffSet() throws InterruptedException { CloudEvent cloudEvent = createDefaultCloudEvent(); instance.putMessage(TEST_TOPIC, cloudEvent); CloudEvent cloudEventResult = instance.getMessage(TEST_TOPIC, OFF_SET); - Assert.assertNotNull(cloudEventResult); + Assertions.assertNotNull(cloudEventResult); } @Test @@ -87,7 +87,7 @@ public void testCheckTopicExist() throws InterruptedException { CloudEvent cloudEvent = createDefaultCloudEvent(); instance.putMessage(TEST_TOPIC, cloudEvent); boolean exists = instance.checkTopicExist(TEST_TOPIC); - Assert.assertTrue(exists); + Assertions.assertTrue(exists); } @Test @@ -97,6 +97,6 @@ public void testDeleteTopicIfExist() throws InterruptedException { instance.putMessage(TEST_TOPIC, cloudEvent); instance.deleteTopicIfExist(TEST_TOPIC); boolean exists = instance.checkTopicExist(TEST_TOPIC); - Assert.assertFalse(exists); + Assertions.assertFalse(exists); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/task/HistoryMessageClearTest.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/task/HistoryMessageClearTest.java index 052e74d34c..9a9b50fce3 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/task/HistoryMessageClearTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/task/HistoryMessageClearTest.java @@ -32,9 +32,9 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class HistoryMessageClearTest { @@ -42,7 +42,7 @@ public class HistoryMessageClearTest { private ConcurrentHashMap messageContainer; private HistoryMessageClear historyMessageClear; - @Before + @BeforeEach public void setUp() throws InterruptedException { messageEntity = createMessageEntity(new TopicMetadata(TEST_TOPIC), createDefaultCloudEvent(), OFF_SET, EXCEEDED_MESSAGE_STORE_WINDOW); messageContainer = createMessageContainer(new TopicMetadata(TEST_TOPIC), messageEntity); @@ -53,6 +53,6 @@ public void setUp() throws InterruptedException { public void testClearMessages() { historyMessageClear.clearMessages(); MessageQueue updatedMessageQueue = messageContainer.get(new TopicMetadata(TEST_TOPIC)); - Assert.assertTrue(Arrays.stream(updatedMessageQueue.items).allMatch(Objects::isNull)); + Assertions.assertTrue(Arrays.stream(updatedMessageQueue.getItems()).allMatch(Objects::isNull)); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/task/SubscribeTest.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/task/SubscribeTest.java index 2b938075d8..bc11c9b0aa 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/task/SubscribeTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/broker/task/SubscribeTest.java @@ -28,16 +28,16 @@ import org.apache.eventmesh.api.EventMeshAsyncConsumeContext; import org.apache.eventmesh.storage.standalone.broker.StandaloneBroker; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import io.cloudevents.CloudEvent; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class SubscribeTest { @Mock @@ -59,6 +59,6 @@ public void testSubscribe() { @Test public void testShutdown() { subscribe = new Subscribe(TEST_TOPIC, standaloneBroker, eventListener); - Assert.assertTrue(subscribe.isRunning()); + Assertions.assertTrue(subscribe.isRunning()); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/consumer/StandaloneConsumerTest.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/consumer/StandaloneConsumerTest.java index 02588a971e..1a74ebbb48 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/consumer/StandaloneConsumerTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/consumer/StandaloneConsumerTest.java @@ -25,16 +25,16 @@ import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import io.cloudevents.CloudEvent; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class StandaloneConsumerTest { @Mock @@ -42,7 +42,7 @@ public class StandaloneConsumerTest { private StandaloneConsumer standaloneConsumer; private List cloudEvents; - @Before + @BeforeEach public void setUp() { standaloneConsumer = new StandaloneConsumer(new Properties()); cloudEvents = createCloudEvents(); @@ -50,23 +50,23 @@ public void setUp() { @Test public void testIsStarted() { - Assert.assertFalse(standaloneConsumer.isStarted()); + Assertions.assertFalse(standaloneConsumer.isStarted()); } @Test public void testIsClosed() { - Assert.assertTrue(standaloneConsumer.isClosed()); + Assertions.assertTrue(standaloneConsumer.isClosed()); } @Test public void testStart() { standaloneConsumer.start(); - Assert.assertTrue(standaloneConsumer.isStarted()); + Assertions.assertTrue(standaloneConsumer.isStarted()); } @Test public void testShutdown() { standaloneConsumer.shutdown(); - Assert.assertTrue(standaloneConsumer.isClosed()); + Assertions.assertTrue(standaloneConsumer.isClosed()); } } diff --git a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/producer/StandaloneProducerTest.java b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/producer/StandaloneProducerTest.java index 89c8c66f7f..37cdc02c6a 100644 --- a/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/producer/StandaloneProducerTest.java +++ b/eventmesh-storage-plugin/eventmesh-storage-standalone/src/test/java/org/apache/eventmesh/storage/standalone/producer/StandaloneProducerTest.java @@ -22,9 +22,9 @@ import java.util.Properties; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import io.cloudevents.CloudEvent; @@ -32,37 +32,37 @@ public class StandaloneProducerTest { private StandaloneProducer standaloneProducer; - @Before + @BeforeEach public void setUp() { standaloneProducer = new StandaloneProducer(new Properties()); } @Test public void testIsStarted() { - Assert.assertFalse(standaloneProducer.isStarted()); + Assertions.assertFalse(standaloneProducer.isStarted()); } @Test public void testIsClosed() { - Assert.assertTrue(standaloneProducer.isClosed()); + Assertions.assertTrue(standaloneProducer.isClosed()); } @Test public void testStart() { standaloneProducer.start(); - Assert.assertTrue(standaloneProducer.isStarted()); + Assertions.assertTrue(standaloneProducer.isStarted()); } @Test public void testShutdown() { standaloneProducer.shutdown(); - Assert.assertTrue(standaloneProducer.isClosed()); + Assertions.assertTrue(standaloneProducer.isClosed()); } @Test public void testPublish() { CloudEvent cloudEvent = TestUtils.createDefaultCloudEvent(); SendResult sendResult = standaloneProducer.publish(cloudEvent); - Assert.assertNotNull(sendResult); + Assertions.assertNotNull(sendResult); } } diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/AbstractTraceService.java b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/AbstractTraceService.java new file mode 100644 index 0000000000..318025f74f --- /dev/null +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/main/java/org/apache/eventmesh/trace/api/AbstractTraceService.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.trace.api; + +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; +import org.apache.eventmesh.trace.api.config.ExporterConfiguration; +import org.apache.eventmesh.trace.api.exception.TraceException; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import io.opentelemetry.api.OpenTelemetry; +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.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import io.opentelemetry.sdk.trace.SpanProcessor; + +import lombok.Getter; +import lombok.Setter; + +/** + * The abstract base class for EventMeshTraceService's implementations + */ +@Getter +@Setter +public abstract class AbstractTraceService implements EventMeshTraceService { + + protected transient SdkTracerProvider sdkTracerProvider; + + protected transient Tracer tracer; + + protected transient TextMapPropagator textMapPropagator; + + /** + * Unified configuration class corresponding to exporter.properties + */ + protected transient ExporterConfiguration exporterConfiguration; + + protected transient Thread shutdownHook; + + @Override + public Context extractFrom(final Context context, final Map carrier) throws TraceException { + textMapPropagator.extract(context, carrier, new TextMapGetter>() { + + @Override + public Iterable keys(@Nonnull final Map carrier) { + return carrier.keySet(); + } + + @Nullable + @Override + public String get(final @Nonnull Map carrier, final String key) { + return Optional.ofNullable(carrier.get(key)).map(Objects::toString).orElse(null); + } + }); + return context; + } + + @Override + public void inject(Context context, Map map) { + textMapPropagator.inject(context, map, (carrier, key, value) -> map.put(key, value)); + } + + @Override + public Span createSpan(final String spanName, + final SpanKind spanKind, + final long startTimestamp, + final TimeUnit timeUnit, + final Context context, + final boolean isSpanFinishInOtherThread) throws TraceException { + return tracer.spanBuilder(spanName) + .setParent(context) + .setSpanKind(spanKind) + .setStartTimestamp(startTimestamp, 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() throws TraceException { + try { + if (sdkTracerProvider != null) { + sdkTracerProvider.close(); + } + } catch (Exception e) { + throw new TraceException("trace close error", e); + } + } + + /** + * Init the common fields + * + * @param spanProcessor + * @param serviceNameResource + */ + protected void initVars(SpanProcessor spanProcessor, Resource serviceNameResource) { + SdkTracerProviderBuilder builder = SdkTracerProvider.builder() + .addSpanProcessor(spanProcessor); + if (serviceNameResource != null) { + builder.setResource(Resource.getDefault().merge(serviceNameResource)); + } + sdkTracerProvider = builder.build(); + + final OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() + .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) + .setTracerProvider(sdkTracerProvider) + .build(); + + tracer = openTelemetry.getTracer(EventMeshTraceConstants.SERVICE_NAME); + textMapPropagator = openTelemetry.getPropagators().getTextMapPropagator(); + shutdownHook = new Thread(sdkTracerProvider::close); + shutdownHook.setDaemon(true); + Runtime.getRuntime().addShutdownHook(shutdownHook); + } +} 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 index e0f4e18b6b..d20a03f4cc 100644 --- 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 @@ -36,10 +36,10 @@ public interface EventMeshTraceService { void init() throws TraceException; - //extract attr from carrier to context + // extract attr from carrier to context Context extractFrom(Context context, Map carrier) throws TraceException; - //inject attr from context to carrier + // inject attr from context to carrier void inject(Context context, Map carrier); Span createSpan(String spanName, SpanKind spanKind, long startTimestamp, TimeUnit timeUnit, 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 index 41c1f34192..544da60a57 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.trace.api.common; - public class EventMeshTraceConstants { public static final String TRACE_EVENTMESH_SDK_CLIENT_SPAN = "eventmesh-sdk-client-span"; @@ -29,4 +28,7 @@ public class EventMeshTraceConstants { 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"; + + // Name of the service(using the instrumentationName) + public static final String SERVICE_NAME = "eventmesh_trace"; } diff --git a/eventmesh-trace-plugin/eventmesh-trace-api/src/test/java/org/apache/eventmesh/trace/api/config/ExporterConfigurationTest.java b/eventmesh-trace-plugin/eventmesh-trace-api/src/test/java/org/apache/eventmesh/trace/api/config/ExporterConfigurationTest.java index a0900cf05a..35b3bfb58b 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-api/src/test/java/org/apache/eventmesh/trace/api/config/ExporterConfigurationTest.java +++ b/eventmesh-trace-plugin/eventmesh-trace-api/src/test/java/org/apache/eventmesh/trace/api/config/ExporterConfigurationTest.java @@ -19,8 +19,8 @@ import org.apache.eventmesh.common.config.ConfigService; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class ExporterConfigurationTest { @@ -29,9 +29,9 @@ public void testGetExporterConfiguration() { ConfigService configService = ConfigService.getInstance(); ExporterConfiguration config = configService.buildConfigInstance(ExporterConfiguration.class); - Assert.assertEquals(816, config.getEventMeshTraceMaxExportSize()); - Assert.assertEquals(1816, config.getEventMeshTraceMaxQueueSize()); - Assert.assertEquals(2816, config.getEventMeshTraceExportTimeout()); - Assert.assertEquals(3816, config.getEventMeshTraceExportInterval()); + Assertions.assertEquals(816, config.getEventMeshTraceMaxExportSize()); + Assertions.assertEquals(1816, config.getEventMeshTraceMaxQueueSize()); + Assertions.assertEquals(2816, config.getEventMeshTraceExportTimeout()); + Assertions.assertEquals(3816, config.getEventMeshTraceExportInterval()); } } \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-jaeger/build.gradle b/eventmesh-trace-plugin/eventmesh-trace-jaeger/build.gradle index 2a422e1762..76a50cffe0 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-jaeger/build.gradle +++ b/eventmesh-trace-plugin/eventmesh-trace-jaeger/build.gradle @@ -36,6 +36,5 @@ dependencies { testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' - testImplementation "org.mockito:mockito-core" testImplementation "org.mockito:mockito-inline" } diff --git a/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/main/java/org/apache/eventmesh/trace/jaeger/JaegerTraceService.java b/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/main/java/org/apache/eventmesh/trace/jaeger/JaegerTraceService.java index 20b3fb0b7e..57b61421e9 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/main/java/org/apache/eventmesh/trace/jaeger/JaegerTraceService.java +++ b/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/main/java/org/apache/eventmesh/trace/jaeger/JaegerTraceService.java @@ -20,62 +20,33 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.trace.api.EventMeshTraceService; -import org.apache.eventmesh.trace.api.config.ExporterConfiguration; +import org.apache.eventmesh.trace.api.AbstractTraceService; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; import org.apache.eventmesh.trace.api.exception.TraceException; -import org.apache.eventmesh.trace.jaeger.common.JaegerConstants; import org.apache.eventmesh.trace.jaeger.config.JaegerConfiguration; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; -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.exporter.jaeger.JaegerGrpcSpanExporter; -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; -import lombok.Data; +import lombok.Getter; +import lombok.Setter; @Config(field = "jaegerConfiguration") @Config(field = "exporterConfiguration") -@Data -public class JaegerTraceService implements EventMeshTraceService { - - private transient SdkTracerProvider sdkTracerProvider; - - private transient Tracer tracer; - - private transient TextMapPropagator textMapPropagator; +public class JaegerTraceService extends AbstractTraceService { /** * Unified configuration class corresponding to jaeger.properties */ + @Getter + @Setter private transient JaegerConfiguration jaegerConfiguration; - /** - * Unified configuration class corresponding to exporter.properties - */ - private transient ExporterConfiguration exporterConfiguration; - - private transient Thread shutdownHook; - @Override public void init() throws TraceException { // jaeger's config @@ -99,90 +70,15 @@ public void init() throws TraceException { .setMaxQueueSize(eventMeshTraceMaxQueueSize) .build(); + // set the trace service's name final Resource serviceNameResource = - Resource.create(Attributes.of(stringKey("service.name"), JaegerConstants.SERVICE_NAME)); - - sdkTracerProvider = SdkTracerProvider.builder() - .addSpanProcessor(spanProcessor) - .setResource(Resource.getDefault().merge(serviceNameResource)) - .build(); - - final OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() - .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) - .setTracerProvider(sdkTracerProvider) - .build(); - - tracer = openTelemetry.getTracer(JaegerConstants.SERVICE_NAME); - textMapPropagator = openTelemetry.getPropagators().getTextMapPropagator(); - - shutdownHook = new Thread(sdkTracerProvider::close); - shutdownHook.setDaemon(true); - Runtime.getRuntime().addShutdownHook(shutdownHook); - } + Resource.create(Attributes.of(stringKey("service.name"), EventMeshTraceConstants.SERVICE_NAME)); - @Override - public Context extractFrom(final Context context, final Map carrier) throws TraceException { - textMapPropagator.extract(context, carrier, new TextMapGetter>() { - @Override - public Iterable keys(@Nonnull final Map carrier) { - return carrier.keySet(); - } - - @Nullable - @Override - public String get(final @Nonnull Map carrier, final String key) { - return Optional.ofNullable(carrier.get(key)).map(Objects::toString).orElse(null); - } - }); - return context; - } - - @Override - public void inject(final Context context, final Map carrier) { - textMapPropagator.inject(context, carrier, (cr, key, value) -> { - if (cr != null) { - cr.put(key, value); - } - }); - } - - @Override - public Span createSpan(final String spanName, final SpanKind spanKind, final long startTimestamp, - final TimeUnit timeUnit, final Context context, - final boolean isSpanFinishInOtherThread) throws TraceException { - return tracer.spanBuilder(spanName) - .setParent(context) - .setSpanKind(spanKind) - .setStartTimestamp(startTimestamp, timeUnit) - .startSpan(); - } - - @Override - public Span createSpan(final String spanName, final SpanKind spanKind, final Context context, - final boolean isSpanFinishInOtherThread) throws TraceException { - return tracer.spanBuilder(spanName) - .setParent(context) - .setSpanKind(spanKind) - .setStartTimestamp(System.currentTimeMillis(), TimeUnit.MILLISECONDS) - .startSpan(); - } - - @Override - public void shutdown() throws TraceException { - try { - if (sdkTracerProvider != null) { - sdkTracerProvider.close(); - } - } catch (Exception e) { - throw new TraceException("trace close error", e); - } + initVars(spanProcessor, serviceNameResource); } public JaegerConfiguration getClientConfiguration() { return this.jaegerConfiguration; } - public ExporterConfiguration getExporterConfiguration() { - return this.exporterConfiguration; - } } diff --git a/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/main/java/org/apache/eventmesh/trace/jaeger/common/JaegerConstants.java b/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/main/java/org/apache/eventmesh/trace/jaeger/common/JaegerConstants.java deleted file mode 100644 index 622b637744..0000000000 --- a/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/main/java/org/apache/eventmesh/trace/jaeger/common/JaegerConstants.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 org.apache.eventmesh.trace.jaeger.common; - -public class JaegerConstants { - - public static final String SERVICE_NAME = "eventmesh_trace"; -} \ No newline at end of file diff --git a/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/test/java/org/apache/eventmesh/trace/jaeger/JaegerTraceServiceTest.java b/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/test/java/org/apache/eventmesh/trace/jaeger/JaegerTraceServiceTest.java index 29defd5448..45c4d4a06a 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/test/java/org/apache/eventmesh/trace/jaeger/JaegerTraceServiceTest.java +++ b/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/test/java/org/apache/eventmesh/trace/jaeger/JaegerTraceServiceTest.java @@ -17,14 +17,16 @@ package org.apache.eventmesh.trace.jaeger; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.apache.eventmesh.common.utils.ReflectUtils; import org.apache.eventmesh.trace.api.TracePluginFactory; import java.lang.reflect.Field; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import io.opentelemetry.sdk.trace.SdkTracerProvider; @@ -37,23 +39,30 @@ public void testInit() { (JaegerTraceService) TracePluginFactory.getEventMeshTraceService("jaeger"); jaegerTraceService.init(); - Assert.assertNotNull(jaegerTraceService.getSdkTracerProvider()); - Assert.assertNotNull(jaegerTraceService.getShutdownHook()); + assertNotNull(jaegerTraceService.getSdkTracerProvider()); + assertNotNull(jaegerTraceService.getShutdownHook()); IllegalArgumentException illegalArgumentException = - assertThrows(IllegalArgumentException.class, () -> - Runtime.getRuntime().addShutdownHook(jaegerTraceService.getShutdownHook())); - Assert.assertEquals(illegalArgumentException.getMessage(), "Hook previously registered"); + assertThrows(IllegalArgumentException.class, () -> Runtime.getRuntime().addShutdownHook(jaegerTraceService.getShutdownHook())); + assertEquals(illegalArgumentException.getMessage(), "Hook previously registered"); } @Test public void testShutdown() throws NoSuchFieldException, IllegalAccessException { - SdkTracerProvider mockSdkTracerProvider = Mockito.mock(SdkTracerProvider.class); JaegerTraceService jaegerTraceService = (JaegerTraceService) TracePluginFactory.getEventMeshTraceService("jaeger"); jaegerTraceService.init(); - Field sdkTracerProviderField = JaegerTraceService.class.getDeclaredField("sdkTracerProvider"); + Field sdkTracerProviderField = null; + try { + sdkTracerProviderField = JaegerTraceService.class.getDeclaredField("sdkTracerProvider"); + } catch (NoSuchFieldException e) { + sdkTracerProviderField = ReflectUtils.lookUpFieldByParentClass(JaegerTraceService.class, "sdkTracerProvider"); + if (sdkTracerProviderField == null) { + throw e; + } + } sdkTracerProviderField.setAccessible(true); + SdkTracerProvider mockSdkTracerProvider = Mockito.mock(SdkTracerProvider.class); sdkTracerProviderField.set(jaegerTraceService, mockSdkTracerProvider); jaegerTraceService.shutdown(); diff --git a/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/test/java/org/apache/eventmesh/trace/jaeger/config/JaegerConfigurationTest.java b/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/test/java/org/apache/eventmesh/trace/jaeger/config/JaegerConfigurationTest.java index 4983dd176f..c5e1eb2297 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/test/java/org/apache/eventmesh/trace/jaeger/config/JaegerConfigurationTest.java +++ b/eventmesh-trace-plugin/eventmesh-trace-jaeger/src/test/java/org/apache/eventmesh/trace/jaeger/config/JaegerConfigurationTest.java @@ -17,12 +17,13 @@ package org.apache.eventmesh.trace.jaeger.config; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.apache.eventmesh.trace.api.TracePluginFactory; import org.apache.eventmesh.trace.api.config.ExporterConfiguration; import org.apache.eventmesh.trace.jaeger.JaegerTraceService; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; public class JaegerConfigurationTest { @@ -38,14 +39,14 @@ public void testGetConfiguration() { } private void assertClientConfig(JaegerConfiguration config) { - Assert.assertEquals("localhost", config.getEventMeshJaegerIp()); - Assert.assertEquals(14250, config.getEventMeshJaegerPort()); + assertEquals("localhost", config.getEventMeshJaegerIp()); + assertEquals(14250, config.getEventMeshJaegerPort()); } private void assertBaseConfig(ExporterConfiguration config) { - Assert.assertEquals(816, config.getEventMeshTraceMaxExportSize()); - Assert.assertEquals(1816, config.getEventMeshTraceMaxQueueSize()); - Assert.assertEquals(2816, config.getEventMeshTraceExportTimeout()); - Assert.assertEquals(3816, config.getEventMeshTraceExportInterval()); + assertEquals(816, config.getEventMeshTraceMaxExportSize()); + assertEquals(1816, config.getEventMeshTraceMaxQueueSize()); + assertEquals(2816, config.getEventMeshTraceExportTimeout()); + assertEquals(3816, config.getEventMeshTraceExportInterval()); } } diff --git a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/build.gradle b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/build.gradle index 0880e4336f..0758ba291e 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/build.gradle +++ b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/build.gradle @@ -46,6 +46,5 @@ dependencies { implementation "io.grpc:grpc-netty" implementation "io.grpc:grpc-netty-shaded" - testImplementation "org.mockito:mockito-core" testImplementation "org.mockito:mockito-inline" } diff --git a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/PinpointTraceService.java b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/PinpointTraceService.java index 7e6fcc6aa3..7513574e64 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/PinpointTraceService.java +++ b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/PinpointTraceService.java @@ -18,64 +18,33 @@ package org.apache.eventmesh.trace.pinpoint; import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.trace.api.EventMeshTraceService; -import org.apache.eventmesh.trace.api.config.ExporterConfiguration; +import org.apache.eventmesh.trace.api.AbstractTraceService; import org.apache.eventmesh.trace.api.exception.TraceException; -import org.apache.eventmesh.trace.pinpoint.common.PinpointConstants; import org.apache.eventmesh.trace.pinpoint.config.PinpointConfiguration; import org.apache.eventmesh.trace.pinpoint.exporter.PinpointSpanExporter; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; - -import io.opentelemetry.api.OpenTelemetry; -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.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; -import lombok.Data; +import lombok.Getter; +import lombok.Setter; /** * https://github.com/pinpoint-apm/pinpoint */ @Config(field = "pinpointConfiguration") @Config(field = "exporterConfiguration") -@Data -public class PinpointTraceService implements EventMeshTraceService { - - private transient SdkTracerProvider sdkTracerProvider; - - private transient Tracer tracer; - - private transient TextMapPropagator textMapPropagator; +public class PinpointTraceService extends AbstractTraceService { /** * Unified configuration class corresponding to pinpoint.properties */ + @Getter + @Setter private transient PinpointConfiguration pinpointConfiguration; - /** - * Unified configuration class corresponding to exporter.properties - */ - private transient ExporterConfiguration exporterConfiguration; - - private transient SpanProcessor spanProcessor; - - private transient Thread shutdownHook; - @Override public void init() throws TraceException { final long eventMeshTraceExportInterval = exporterConfiguration.getEventMeshTraceExportInterval(); @@ -83,117 +52,23 @@ public void init() throws TraceException { final int eventMeshTraceMaxExportSize = exporterConfiguration.getEventMeshTraceMaxExportSize(); final int eventMeshTraceMaxQueueSize = exporterConfiguration.getEventMeshTraceMaxQueueSize(); - spanProcessor = BatchSpanProcessor.builder( - new PinpointSpanExporter( - pinpointConfiguration.getAgentId(), - pinpointConfiguration.getAgentName(), - pinpointConfiguration.getApplicationName(), - pinpointConfiguration.getGrpcTransportConfig())) + SpanProcessor spanProcessor = BatchSpanProcessor.builder( + new PinpointSpanExporter( + pinpointConfiguration.getAgentId(), + pinpointConfiguration.getAgentName(), + pinpointConfiguration.getApplicationName(), + pinpointConfiguration.getGrpcTransportConfig())) .setScheduleDelay(eventMeshTraceExportInterval, TimeUnit.SECONDS) .setExporterTimeout(eventMeshTraceExportTimeout, TimeUnit.SECONDS) .setMaxExportBatchSize(eventMeshTraceMaxExportSize) .setMaxQueueSize(eventMeshTraceMaxQueueSize) .build(); - sdkTracerProvider = SdkTracerProvider.builder() - .addSpanProcessor(spanProcessor) - .build(); - - final OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() - .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) - .setTracerProvider(sdkTracerProvider) - .build(); - - tracer = openTelemetry.getTracer(PinpointConstants.SERVICE_NAME); - - textMapPropagator = openTelemetry.getPropagators().getTextMapPropagator(); - - shutdownHook = new Thread(sdkTracerProvider::close); - shutdownHook.setDaemon(true); - Runtime.getRuntime().addShutdownHook(shutdownHook); - } - - @Override - public Context extractFrom(final Context context, final Map carrier) throws TraceException { - textMapPropagator.extract(context, carrier, new TextMapGetter>() { - @Override - public Iterable keys(final @Nonnull Map carrier) { - return carrier.keySet(); - } - - @Override - public String get(final @Nonnull Map carrier, final @Nonnull String key) { - return Optional.ofNullable(carrier.get(key)).map(Objects::toString).orElse(null); - } - }); - return context; - - } - - @Override - public void inject(final Context context, final Map carrier) { - textMapPropagator.inject(context, carrier, (cr, key, value) -> { - if (cr != null) { - cr.put(key, value); - } - }); - } - - @Override - public Span createSpan(final String spanName, - final SpanKind spanKind, - final long startTimestamp, - final TimeUnit timeUnit, - final Context context, - final boolean isSpanFinishInOtherThread) throws TraceException { - return tracer.spanBuilder(spanName) - .setParent(context) - .setSpanKind(spanKind) - .setStartTimestamp(startTimestamp, timeUnit) - .startSpan(); - } - - @Override - public Span createSpan(final String spanName, final SpanKind spanKind, final Context context, - final boolean isSpanFinishInOtherThread) throws TraceException { - return tracer.spanBuilder(spanName) - .setParent(context) - .setSpanKind(spanKind) - .setStartTimestamp(System.currentTimeMillis(), TimeUnit.MILLISECONDS) - .startSpan(); - } - - @Override - public void shutdown() throws TraceException { - - Exception ex = null; - - try { - if (sdkTracerProvider != null) { - sdkTracerProvider.close(); - } - } catch (Exception e) { - ex = e; - } - - try { - if (spanProcessor != null) { - spanProcessor.close(); - } - } catch (Exception e) { - ex = e; - } - - if (ex != null) { - throw new TraceException("trace close error", ex); - } + initVars(spanProcessor, null); } public PinpointConfiguration getClientConfiguration() { return this.pinpointConfiguration; } - public ExporterConfiguration getExporterConfiguration() { - return this.exporterConfiguration; - } } diff --git a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/common/PinpointConstants.java b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/common/PinpointConstants.java index 9ebf68fd70..c704a0e879 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/common/PinpointConstants.java +++ b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/common/PinpointConstants.java @@ -19,8 +19,6 @@ public class PinpointConstants { - public static final String SERVICE_NAME = "eventmesh_trace"; - public static final String REQ_IP = "req0ip"; public static final String UNKNOWN_REQ_IP = "unknown"; diff --git a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/exporter/PinpointSpanExporter.java b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/exporter/PinpointSpanExporter.java index e1e6d3fdbc..24e41039f3 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/exporter/PinpointSpanExporter.java +++ b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/main/java/org/apache/eventmesh/trace/pinpoint/exporter/PinpointSpanExporter.java @@ -25,7 +25,7 @@ import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.common.utils.IPUtils; import org.apache.eventmesh.common.utils.JsonUtils; -import org.apache.eventmesh.trace.pinpoint.common.PinpointConstants; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; import org.apache.commons.collections4.CollectionUtils; @@ -139,8 +139,7 @@ public PinpointSpanExporter(final String agentId, agentName, applicationName, ServiceType.UNDEFINED.getCode(), - agentStartTime - ); + agentStartTime); this.agentInfoSender = createAgentInfoSender(); this.agentInfoSender.start(); @@ -176,15 +175,13 @@ private AgentInfoSender createAgentInfoSender() { JvmGcType.UNKNOWN); final ServerMetaDataRegistryService serverMetaDataRegistryService = new DefaultServerMetaDataRegistryService( - Collections.emptyList() - ); - serverMetaDataRegistryService.setServerName(PinpointConstants.SERVICE_NAME); + Collections.emptyList()); + serverMetaDataRegistryService.setServerName(EventMeshTraceConstants.SERVICE_NAME); final AgentInfoFactory agentInfoFactory = new AgentInfoFactory( agentInformationProvider.createAgentInformation(), serverMetaDataRegistryService, - jvmInformation - ); + jvmInformation); return new AgentInfoSender.Builder(agentGrpcDataSender, agentInfoFactory).build(); } @@ -196,14 +193,12 @@ private SpanGrpcDataSender createSpanGrpcDataSender() { new GrpcSpanMessageConverter( agentId, ServiceType.STAND_ALONE.getCode(), - new GrpcSpanProcessorV2() - ); + new GrpcSpanProcessorV2()); final StreamState streamState = new SimpleStreamState( grpcTransportConfig.getSpanClientOption().getLimitCount(), - grpcTransportConfig.getSpanClientOption().getLimitTime() - ); + grpcTransportConfig.getSpanClientOption().getLimitTime()); return new SpanGrpcDataSender( grpcTransportConfig.getSpanCollectorIp(), @@ -212,8 +207,7 @@ private SpanGrpcDataSender createSpanGrpcDataSender() { messageConverter, reconnectExecutor, spanChannelFactory, - streamState - ); + streamState); } private ChannelFactory createAgentChannelFactory() { @@ -360,8 +354,7 @@ private static long toMillis(final long epochNanos) { private static long hex32StringToLong(final String hex32String) { final CharSequence charSequence = new StringBuilder().append(hex32String); return OtelEncodingUtils.isValidBase16String(charSequence) - ? - OtelEncodingUtils.longFromBase16String(charSequence, 0) + ? OtelEncodingUtils.longFromBase16String(charSequence, 0) & OtelEncodingUtils.longFromBase16String(charSequence, 16) : hex32String.hashCode(); } diff --git a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/PinpointTraceServiceTest.java b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/PinpointTraceServiceTest.java index 770cd2065b..2fba35b589 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/PinpointTraceServiceTest.java +++ b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/PinpointTraceServiceTest.java @@ -17,14 +17,15 @@ package org.apache.eventmesh.trace.pinpoint; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.apache.eventmesh.common.utils.ReflectUtils; import org.apache.eventmesh.trace.api.TracePluginFactory; import java.lang.reflect.Field; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import io.opentelemetry.sdk.trace.SdkTracerProvider; @@ -38,20 +39,26 @@ public void testInit() { pinpointTraceService.init(); IllegalArgumentException illegalArgumentException = - assertThrows(IllegalArgumentException.class, () -> - Runtime.getRuntime().addShutdownHook(pinpointTraceService.getShutdownHook())); - Assert.assertEquals(illegalArgumentException.getMessage(), "Hook previously registered"); + assertThrows(IllegalArgumentException.class, () -> Runtime.getRuntime().addShutdownHook(pinpointTraceService.getShutdownHook())); + Assertions.assertEquals(illegalArgumentException.getMessage(), "Hook previously registered"); } @Test public void testShutdown() throws Exception { - SdkTracerProvider mockSdkTracerProvider = Mockito.mock(SdkTracerProvider.class); - PinpointTraceService pinpointTraceService = (PinpointTraceService) TracePluginFactory.getEventMeshTraceService("pinpoint"); pinpointTraceService.init(); - Field sdkTracerProviderField = PinpointTraceService.class.getDeclaredField("sdkTracerProvider"); + Field sdkTracerProviderField = null; + try { + sdkTracerProviderField = PinpointTraceService.class.getDeclaredField("sdkTracerProvider"); + } catch (NoSuchFieldException e) { + sdkTracerProviderField = ReflectUtils.lookUpFieldByParentClass(PinpointTraceService.class, "sdkTracerProvider"); + if (sdkTracerProviderField == null) { + throw e; + } + } sdkTracerProviderField.setAccessible(true); + SdkTracerProvider mockSdkTracerProvider = Mockito.mock(SdkTracerProvider.class); sdkTracerProviderField.set(pinpointTraceService, mockSdkTracerProvider); pinpointTraceService.shutdown(); diff --git a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/config/PinpointConfigurationTest.java b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/config/PinpointConfigurationTest.java index 34aeea7628..f2dc0d46b9 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/config/PinpointConfigurationTest.java +++ b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/config/PinpointConfigurationTest.java @@ -17,13 +17,12 @@ package org.apache.eventmesh.trace.pinpoint.config; - import org.apache.eventmesh.trace.api.TracePluginFactory; import org.apache.eventmesh.trace.api.config.ExporterConfiguration; import org.apache.eventmesh.trace.pinpoint.PinpointTraceService; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import com.navercorp.pinpoint.profiler.context.grpc.config.GrpcTransportConfig; @@ -41,25 +40,25 @@ public void getConfigWhenPinpointTraceInit() { } private void assertClientConfig(PinpointConfiguration config) { - Assert.assertEquals("eventmesh", config.getApplicationName()); - Assert.assertEquals("eventmesh", config.getAgentName()); - Assert.assertEquals("eventmesh-01", config.getAgentId()); + Assertions.assertEquals("eventmesh", config.getApplicationName()); + Assertions.assertEquals("eventmesh", config.getAgentName()); + Assertions.assertEquals("eventmesh-01", config.getAgentId()); GrpcTransportConfig grpcTransportConfig = config.getGrpcTransportConfig(); - Assert.assertNotNull(grpcTransportConfig); - Assert.assertEquals("127.0.0.1", grpcTransportConfig.getAgentCollectorIp()); - Assert.assertEquals(9991, grpcTransportConfig.getAgentCollectorPort()); - Assert.assertEquals("localhost", grpcTransportConfig.getSpanCollectorIp()); - Assert.assertEquals(9993, grpcTransportConfig.getSpanCollectorPort()); + Assertions.assertNotNull(grpcTransportConfig); + Assertions.assertEquals("127.0.0.1", grpcTransportConfig.getAgentCollectorIp()); + Assertions.assertEquals(9991, grpcTransportConfig.getAgentCollectorPort()); + Assertions.assertEquals("localhost", grpcTransportConfig.getSpanCollectorIp()); + Assertions.assertEquals(9993, grpcTransportConfig.getSpanCollectorPort()); - Assert.assertEquals(123, grpcTransportConfig.getSpanClientOption().getLimitCount()); - Assert.assertEquals(6700, grpcTransportConfig.getSpanClientOption().getLimitTime()); + Assertions.assertEquals(123, grpcTransportConfig.getSpanClientOption().getLimitCount()); + Assertions.assertEquals(6700, grpcTransportConfig.getSpanClientOption().getLimitTime()); } private void assertBaseConfig(ExporterConfiguration config) { - Assert.assertEquals(816, config.getEventMeshTraceMaxExportSize()); - Assert.assertEquals(1816, config.getEventMeshTraceMaxQueueSize()); - Assert.assertEquals(2816, config.getEventMeshTraceExportTimeout()); - Assert.assertEquals(3816, config.getEventMeshTraceExportInterval()); + Assertions.assertEquals(816, config.getEventMeshTraceMaxExportSize()); + Assertions.assertEquals(1816, config.getEventMeshTraceMaxQueueSize()); + Assertions.assertEquals(2816, config.getEventMeshTraceExportTimeout()); + Assertions.assertEquals(3816, config.getEventMeshTraceExportInterval()); } } diff --git a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/exporter/PinpointSpanExporterTest.java b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/exporter/PinpointSpanExporterTest.java index cc4a63af47..5475876cef 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/exporter/PinpointSpanExporterTest.java +++ b/eventmesh-trace-plugin/eventmesh-trace-pinpoint/src/test/java/org/apache/eventmesh/trace/pinpoint/exporter/PinpointSpanExporterTest.java @@ -17,7 +17,6 @@ package org.apache.eventmesh.trace.pinpoint.exporter; - import org.apache.eventmesh.common.utils.RandomStringUtils; import org.apache.eventmesh.trace.api.TracePluginFactory; import org.apache.eventmesh.trace.pinpoint.PinpointTraceService; @@ -28,9 +27,9 @@ import java.util.List; import java.util.UUID; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanContext; @@ -49,7 +48,7 @@ public class PinpointSpanExporterTest { private PinpointSpanExporter exporter; - @Before + @BeforeEach public void setup() { PinpointTraceService pinpointTrace = (PinpointTraceService) TracePluginFactory.getEventMeshTraceService("pinpoint"); @@ -60,31 +59,30 @@ public void setup() { config.getAgentId(), config.getAgentName(), config.getApplicationName(), - config.getGrpcTransportConfig() - ); + config.getGrpcTransportConfig()); } @Test public void exportTest() { Collection spans = new ArrayList<>(); - Assert.assertEquals(CompletableResultCode.ofSuccess(), exporter.export(spans)); + Assertions.assertEquals(CompletableResultCode.ofSuccess(), exporter.export(spans)); spans.add(null); - Assert.assertEquals(CompletableResultCode.ofSuccess(), exporter.export(spans)); + Assertions.assertEquals(CompletableResultCode.ofSuccess(), exporter.export(spans)); spans.clear(); spans.add(new SpanDateTest()); - Assert.assertEquals(CompletableResultCode.ofSuccess(), exporter.export(spans)); + Assertions.assertEquals(CompletableResultCode.ofSuccess(), exporter.export(spans)); } @Test public void flushTest() { - Assert.assertEquals(CompletableResultCode.ofSuccess(), exporter.flush()); + Assertions.assertEquals(CompletableResultCode.ofSuccess(), exporter.flush()); } @Test public void shutdownTest() { - Assert.assertEquals(CompletableResultCode.ofSuccess(), exporter.shutdown()); + Assertions.assertEquals(CompletableResultCode.ofSuccess(), exporter.shutdown()); } /** diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/build.gradle b/eventmesh-trace-plugin/eventmesh-trace-zipkin/build.gradle index 505845ff1d..d687bb609c 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-zipkin/build.gradle +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/build.gradle @@ -30,6 +30,5 @@ dependencies { testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' - testImplementation "org.mockito:mockito-core" testImplementation "org.mockito:mockito-inline" } 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 index ec7e1cb09c..ed98b5a3b0 100644 --- 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 @@ -20,74 +20,46 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import org.apache.eventmesh.common.config.Config; -import org.apache.eventmesh.trace.api.EventMeshTraceService; -import org.apache.eventmesh.trace.api.config.ExporterConfiguration; +import org.apache.eventmesh.trace.api.AbstractTraceService; +import org.apache.eventmesh.trace.api.common.EventMeshTraceConstants; import org.apache.eventmesh.trace.api.exception.TraceException; import org.apache.eventmesh.trace.zipkin.common.ZipkinConstants; import org.apache.eventmesh.trace.zipkin.config.ZipkinConfiguration; -import java.util.Map; -import java.util.Optional; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; - -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.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; -import lombok.Data; - +import lombok.Getter; +import lombok.Setter; /** * ZipkinTraceService */ @Config(field = "zipkinConfiguration") @Config(field = "exporterConfiguration") -@Data -public class ZipkinTraceService implements EventMeshTraceService { - - private transient SdkTracerProvider sdkTracerProvider; - private transient SpanProcessor spanProcessor; - - private transient Thread shutdownHook; - - - private transient Tracer tracer; - private transient TextMapPropagator textMapPropagator; +@Getter +@Setter +public class ZipkinTraceService extends AbstractTraceService { /** * Unified configuration class corresponding to zipkin.properties */ private transient ZipkinConfiguration zipkinConfiguration; - /** - * Unified configuration class corresponding to exporter.properties - */ - private transient ExporterConfiguration exporterConfiguration; - private transient ZipkinSpanExporter zipkinExporter; @Override public void init() { - //zipkin's config + // zipkin's config final String eventMeshZipkinIP = zipkinConfiguration.getEventMeshZipkinIP(); final int eventMeshZipkinPort = zipkinConfiguration.getEventMeshZipkinPort(); - //exporter's config + // exporter's config final int eventMeshTraceExportInterval = exporterConfiguration.getEventMeshTraceExportInterval(); final int eventMeshTraceExportTimeout = exporterConfiguration.getEventMeshTraceExportTimeout(); final int eventMeshTraceMaxExportSize = exporterConfiguration.getEventMeshTraceMaxExportSize(); @@ -96,80 +68,22 @@ public void init() { final String httpUrl = String.format("http://%s:%s", eventMeshZipkinIP, eventMeshZipkinPort); zipkinExporter = ZipkinSpanExporter.builder().setEndpoint(httpUrl + ZipkinConstants.ENDPOINT_V2_SPANS).build(); - spanProcessor = BatchSpanProcessor.builder(zipkinExporter) + SpanProcessor spanProcessor = BatchSpanProcessor.builder(zipkinExporter) .setScheduleDelay(eventMeshTraceExportInterval, TimeUnit.SECONDS) .setExporterTimeout(eventMeshTraceExportTimeout, TimeUnit.SECONDS) .setMaxExportBatchSize(eventMeshTraceMaxExportSize) .setMaxQueueSize(eventMeshTraceMaxQueueSize) .build(); - //set the trace service's name + // set the trace service's name final Resource serviceNameResource = - Resource.create(Attributes.of(stringKey("service.name"), ZipkinConstants.SERVICE_NAME)); - - sdkTracerProvider = SdkTracerProvider.builder() - .addSpanProcessor(spanProcessor) - .setResource(Resource.getDefault().merge(serviceNameResource)) - .build(); - - final OpenTelemetry openTelemetry = OpenTelemetrySdk.builder() - .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) - .setTracerProvider(sdkTracerProvider) - .build(); - - //TODO serviceName??? - tracer = openTelemetry.getTracer(ZipkinConstants.SERVICE_NAME); - textMapPropagator = openTelemetry.getPropagators().getTextMapPropagator(); - shutdownHook = new Thread(sdkTracerProvider::close); - shutdownHook.setDaemon(true); - Runtime.getRuntime().addShutdownHook(shutdownHook); - } - - @Override - public Context extractFrom(Context context, Map map) throws TraceException { - textMapPropagator.extract(context, map, new TextMapGetter>() { - @Override - public Iterable keys(@Nonnull Map carrier) { - return carrier.keySet(); - } + Resource.create(Attributes.of(stringKey("service.name"), EventMeshTraceConstants.SERVICE_NAME)); - @Override - public String get(@Nonnull Map carrier, String key) { - return Optional.ofNullable(carrier.get(key)).map(Object::toString).orElse(null); - } - }); - return context; - } - - @Override - public void inject(Context context, Map map) { - textMapPropagator.inject(context, map, (carrier, key, 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(); + initVars(spanProcessor, serviceNameResource); } @Override public void shutdown() throws TraceException { - //todo: check the spanProcessor if it was already close Exception ex = null; @@ -181,14 +95,6 @@ public void shutdown() throws TraceException { ex = e; } - try { - if (spanProcessor != null) { - spanProcessor.close(); - } - } catch (Exception e) { - ex = e; - } - try { if (zipkinExporter != null) { zipkinExporter.close(); @@ -201,14 +107,10 @@ public void shutdown() throws TraceException { throw new TraceException("trace close error", ex); } - //todo: turn the value of useTrace in AbstractHTTPServer into false + // todo: turn the value of useTrace in AbstractHTTPServer into false } public ZipkinConfiguration getClientConfiguration() { return this.zipkinConfiguration; } - - public ExporterConfiguration getExporterConfiguration() { - return this.exporterConfiguration; - } } diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/common/ZipkinConstants.java b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/common/ZipkinConstants.java index 1ad22e972d..259fad4334 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/common/ZipkinConstants.java +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/main/java/org/apache/eventmesh/trace/zipkin/common/ZipkinConstants.java @@ -19,9 +19,6 @@ public class ZipkinConstants { - // Name of the service(using the instrumentationName) - public static final String SERVICE_NAME = "eventmesh_trace"; - // Zipkin API Endpoints for uploading spans public static final String ENDPOINT_V2_SPANS = "/api/v2/spans"; } diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/TracePluginFactoryTest.java b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/TracePluginFactoryTest.java index 8e9efb3ab7..f648a1dca5 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/TracePluginFactoryTest.java +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/TracePluginFactoryTest.java @@ -17,33 +17,30 @@ package org.apache.eventmesh.trace.zipkin; -import static org.hamcrest.CoreMatchers.is; - import org.apache.eventmesh.trace.api.EventMeshTraceService; import org.apache.eventmesh.trace.api.TracePluginFactory; -import org.hamcrest.MatcherAssert; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class TracePluginFactoryTest { @Test public void testFailedGetTraceService() { - NullPointerException nullPointerException1 = Assert.assertThrows(NullPointerException.class, + NullPointerException nullPointerException1 = Assertions.assertThrows(NullPointerException.class, () -> TracePluginFactory.getEventMeshTraceService(null)); - MatcherAssert.assertThat(nullPointerException1.getMessage(), is("traceServiceType cannot be null")); + Assertions.assertEquals("traceServiceType cannot be null", nullPointerException1.getMessage()); String traceServiceType = "non-Existing"; NullPointerException nullPointerException2 = - Assert.assertThrows(NullPointerException.class, () -> TracePluginFactory.getEventMeshTraceService(traceServiceType)); - MatcherAssert.assertThat(nullPointerException2.getMessage(), is("traceServiceType: " + traceServiceType + " is not supported")); + Assertions.assertThrows(NullPointerException.class, () -> TracePluginFactory.getEventMeshTraceService(traceServiceType)); + Assertions.assertEquals("traceServiceType: " + traceServiceType + " is not supported", nullPointerException2.getMessage()); } @Test public void testSuccessfulGetTraceService() { EventMeshTraceService zipkinTraceService = TracePluginFactory.getEventMeshTraceService("zipkin"); - Assert.assertNotNull(zipkinTraceService); - Assert.assertTrue(zipkinTraceService instanceof ZipkinTraceService); + Assertions.assertNotNull(zipkinTraceService); + Assertions.assertTrue(zipkinTraceService instanceof ZipkinTraceService); } } 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 index f00ee0cc67..9025405497 100644 --- 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 @@ -17,14 +17,15 @@ package org.apache.eventmesh.trace.zipkin; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; +import org.apache.eventmesh.common.utils.ReflectUtils; import org.apache.eventmesh.trace.api.TracePluginFactory; import java.lang.reflect.Field; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import io.opentelemetry.sdk.trace.SdkTracerProvider; @@ -37,24 +38,31 @@ public void testInit() { (ZipkinTraceService) TracePluginFactory.getEventMeshTraceService("zipkin"); zipkinTraceService.init(); - Assert.assertNotNull(zipkinTraceService.getSdkTracerProvider()); - Assert.assertNotNull(zipkinTraceService.getShutdownHook()); + Assertions.assertNotNull(zipkinTraceService.getSdkTracerProvider()); + Assertions.assertNotNull(zipkinTraceService.getShutdownHook()); IllegalArgumentException illegalArgumentException = assertThrows(IllegalArgumentException.class, () -> Runtime.getRuntime().addShutdownHook(zipkinTraceService.getShutdownHook())); - Assert.assertEquals(illegalArgumentException.getMessage(), "Hook previously registered"); + Assertions.assertEquals(illegalArgumentException.getMessage(), "Hook previously registered"); } @Test public void testShutdown() throws Exception { - SdkTracerProvider mockSdkTracerProvider = Mockito.mock(SdkTracerProvider.class); - ZipkinTraceService zipkinTraceService = (ZipkinTraceService) TracePluginFactory.getEventMeshTraceService("zipkin"); zipkinTraceService.init(); - Field sdkTracerProviderField = ZipkinTraceService.class.getDeclaredField("sdkTracerProvider"); + Field sdkTracerProviderField = null; + try { + sdkTracerProviderField = ZipkinTraceService.class.getDeclaredField("sdkTracerProvider"); + } catch (NoSuchFieldException e) { + sdkTracerProviderField = ReflectUtils.lookUpFieldByParentClass(ZipkinTraceService.class, "sdkTracerProvider"); + if (sdkTracerProviderField == null) { + throw e; + } + } sdkTracerProviderField.setAccessible(true); + SdkTracerProvider mockSdkTracerProvider = Mockito.mock(SdkTracerProvider.class); sdkTracerProviderField.set(zipkinTraceService, mockSdkTracerProvider); zipkinTraceService.shutdown(); diff --git a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/config/ZipkinConfigurationTest.java b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/config/ZipkinConfigurationTest.java index 3acb301734..3fb8e4e5f5 100644 --- a/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/config/ZipkinConfigurationTest.java +++ b/eventmesh-trace-plugin/eventmesh-trace-zipkin/src/test/java/org/apache/eventmesh/trace/zipkin/config/ZipkinConfigurationTest.java @@ -21,8 +21,8 @@ import org.apache.eventmesh.trace.api.config.ExporterConfiguration; import org.apache.eventmesh.trace.zipkin.ZipkinTraceService; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class ZipkinConfigurationTest { @@ -38,14 +38,14 @@ public void getConfigWhenZipkinTraceInit() { } private void assertConfig(ZipkinConfiguration config) { - Assert.assertEquals("127.0.0.1", config.getEventMeshZipkinIP()); - Assert.assertEquals(816, config.getEventMeshZipkinPort()); + Assertions.assertEquals("127.0.0.1", config.getEventMeshZipkinIP()); + Assertions.assertEquals(816, config.getEventMeshZipkinPort()); } private void assertBaseConfig(ExporterConfiguration config) { - Assert.assertEquals(816, config.getEventMeshTraceMaxExportSize()); - Assert.assertEquals(1816, config.getEventMeshTraceMaxQueueSize()); - Assert.assertEquals(2816, config.getEventMeshTraceExportTimeout()); - Assert.assertEquals(3816, config.getEventMeshTraceExportInterval()); + Assertions.assertEquals(816, config.getEventMeshTraceMaxExportSize()); + Assertions.assertEquals(1816, config.getEventMeshTraceMaxQueueSize()); + Assertions.assertEquals(2816, config.getEventMeshTraceExportTimeout()); + Assertions.assertEquals(3816, config.getEventMeshTraceExportInterval()); } } diff --git a/eventmesh-transformer/build.gradle b/eventmesh-transformer/build.gradle new file mode 100644 index 0000000000..ba88591b41 --- /dev/null +++ b/eventmesh-transformer/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") +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/ConstantTransformer.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/ConstantTransformer.java new file mode 100644 index 0000000000..dd7c20aace --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/ConstantTransformer.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.transformer; + +public class ConstantTransformer implements Transformer { + + private final String jsonpath; + + ConstantTransformer(String jsonpath) { + this.jsonpath = jsonpath; + } + + @Override + public String transform(String json) throws TransformException { + return this.jsonpath; + } +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/JsonPathParser.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/JsonPathParser.java new file mode 100644 index 0000000000..a0ebde12d2 --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/JsonPathParser.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.transformer; + +import org.apache.eventmesh.common.utils.JsonPathUtils; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; + +public class JsonPathParser { + + protected List variablesList = new ArrayList<>(); + + public List getVariablesList() { + return variablesList; + } + + /** + * parser input jsonpath string into variable list + * + * @param jsonPathString + */ + public JsonPathParser(String jsonPathString) { + JsonNode jsonObject = JsonPathUtils.parseStrict(jsonPathString); + Iterator> fields = jsonObject.fields(); + + while (fields.hasNext()) { + Map.Entry entry = fields.next(); + String name = entry.getKey(); + JsonNode valueNode = entry.getValue(); + if (valueNode.isValueNode()) { + variablesList.add(new Variable(name, valueNode.asText())); + } else { + throw new TransformException("invalid config:" + jsonPathString); + } + + } + + } + + /** + * use jsonpath to match json and return result + * + * @param json + * @return + */ + + public List match(String json) throws JsonProcessingException { + if (json == null || json.isEmpty()) { + return new ArrayList<>(); + } + + List variableList = new ArrayList<>(variablesList.size()); + for (Variable element : variablesList) { + if (JsonPathUtils.isValidAndDefinite(element.getValue())) { + String res = JsonPathUtils.matchJsonPathValueWithString(json, element.getValue()); + Variable variable = new Variable(element.getName(), res); + variableList.add(variable); + } else { + variableList.add(element); + } + + } + return variableList; + } +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/OriginalTransformer.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/OriginalTransformer.java new file mode 100644 index 0000000000..61aa059d59 --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/OriginalTransformer.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.transformer; + +class OriginalTransformer implements Transformer { + + @Override + public String transform(String json) { + return json; + } +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/Template.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/Template.java new file mode 100644 index 0000000000..19c3b5cec3 --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/Template.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.transformer; + +import org.apache.commons.text.StringSubstitutor; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class Template { + + private String template; + + public Template(String template) { + this.template = template; + } + + public String substitute(List variables) throws TransformException { + + Map valuesMap = variables.stream() + .filter(variable -> variable.getValue() != null) + .collect(Collectors.toMap(Variable::getName, Variable::getValue)); + StringSubstitutor sub = new StringSubstitutor(valuesMap); + + return sub.replace(template); + + } + + public String getTemplate() { + return template; + } + + public void setTemplate(String template) { + this.template = template; + } +} \ No newline at end of file diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TemplateTransformer.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TemplateTransformer.java new file mode 100644 index 0000000000..bc9907ff48 --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TemplateTransformer.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.transformer; + +import java.util.List; + +import com.fasterxml.jackson.core.JsonProcessingException; + +class TemplateTransformer implements Transformer { + + private final JsonPathParser jsonPathParser; + + private final Template template; + + TemplateTransformer(JsonPathParser jsonPathParser, Template template) { + this.template = template; + this.jsonPathParser = jsonPathParser; + } + + @Override + public String transform(String json) throws JsonProcessingException { + // 1: get variable match results + List variableList = jsonPathParser.match(json); + // 2: use results replace template + return template.substitute(variableList); + } + +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformException.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformException.java new file mode 100644 index 0000000000..1b11a29d80 --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformException.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.transformer; + +/** + * Transform exception + */ +public class TransformException extends RuntimeException { + + private static final long serialVersionUID = -4351489859520642285L; + + public TransformException(String message) { + super(message); + } + + public TransformException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/Transformer.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/Transformer.java new file mode 100644 index 0000000000..8239dfcb6e --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/Transformer.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.transformer; + +import com.fasterxml.jackson.core.JsonProcessingException; + +/** + * EventMesh transformer interface, specified transformer implementation includes: + * 1. Constant + * 2. Original + * 3. Template + */ +public interface Transformer { + + String transform(String json) throws JsonProcessingException; + +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformerBuilder.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformerBuilder.java new file mode 100644 index 0000000000..e7277af73c --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformerBuilder.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.transformer; + +public class TransformerBuilder { + + public static Transformer buildTransformer(TransformerParam transformerParam) { + switch (transformerParam.getTransformerType()) { + case ORIGINAL: + return buildOriginalTransformer(); + case CONSTANT: + return buildConstantTransformer(transformerParam.getValue()); + case TEMPLATE: + return buildTemplateTransFormer(transformerParam.getValue(), transformerParam.getTemplate()); + default: + throw new TransformException("invalid config"); + } + } + + public static Transformer buildTemplateTransFormer(String jsonContent, String template) { + JsonPathParser jsonPathParser = new JsonPathParser(jsonContent); + Template templateEntry = new Template(template); + return new TemplateTransformer(jsonPathParser, templateEntry); + } + + public static Transformer buildConstantTransformer(String constant) { + return new ConstantTransformer(constant); + } + + public static Transformer buildOriginalTransformer() { + return new OriginalTransformer(); + } + +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformerParam.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformerParam.java new file mode 100644 index 0000000000..d747d7be4c --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformerParam.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.transformer; + +public class TransformerParam { + + private TransformerType transformerType; + private String value; + private String template; + + public TransformerParam() { + } + + public TransformerParam(TransformerType transformerType, String value, String template) { + this.transformerType = transformerType; + this.value = value; + this.template = template; + } + + public TransformerParam(TransformerType transformerType, String value) { + this(transformerType, value, null); + } + + public TransformerType getTransformerType() { + return transformerType; + } + + public void setTransformerType(TransformerType transformerType) { + this.transformerType = transformerType; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getTemplate() { + return template; + } + + public void setTemplate(String template) { + this.template = template; + } + +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformerType.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformerType.java new file mode 100644 index 0000000000..2dc7809478 --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/TransformerType.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.transformer; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum TransformerType { + + ORIGINAL(1, "original"), + CONSTANT(2, "constant"), + TEMPLATE(3, "template"); + + private int code; + + private String type; + + TransformerType(int code, String type) { + this.code = code; + this.type = type; + } + + @JsonCreator + public static TransformerType getItem(String type) { + for (TransformerType transformerType : values()) { + if (Objects.equals(transformerType.getType(), type)) { + return transformerType; + } + } + return null; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + @JsonValue + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/Variable.java b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/Variable.java new file mode 100644 index 0000000000..c9259d335c --- /dev/null +++ b/eventmesh-transformer/src/main/java/org/apache/eventmesh/transformer/Variable.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.transformer; + +public class Variable { + + private String name; + + private String value; + + public Variable(String name, String value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/eventmesh-transformer/src/test/java/org/apache/eventmesh/transformer/TransformTest.java b/eventmesh-transformer/src/test/java/org/apache/eventmesh/transformer/TransformTest.java new file mode 100644 index 0000000000..a55cde0baf --- /dev/null +++ b/eventmesh-transformer/src/test/java/org/apache/eventmesh/transformer/TransformTest.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.transformer; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; + +public class TransformTest { + + public static final String EVENT = "{\n" + + "\"id\": \"5b26115b-73e-cf74a******\",\n" + + " \"specversion\": \"1.0\",\n" + + "\"source\": \"apache.eventmesh\",\n" + + "\"type\": \"object:test\",\n" + + "\"datacontenttype\": \"application/json\",\n" + + "\"subject\": \"xxx.jpg\",\n" + + "\"time\": \"2023-09-17T12:07:48.955Z\",\n" + + "\"data\": {\n" + + "\"name\": \"test-transformer\",\n" + + "\"num\": 100 ,\n" + + "\"boolean\": true,\n" + + "\"nullV\": null\n" + + "}\n" + + " }"; + + @Test + public void testOriginalTransformer() throws JsonProcessingException { + TransformerParam transformerParam = new TransformerParam(); + transformerParam.setTransformerType(TransformerType.ORIGINAL); + + Transformer transformer = TransformerBuilder.buildTransformer(transformerParam); + String output = transformer.transform(EVENT); + Assertions.assertEquals(EVENT, output); + + Transformer transformer1 = TransformerBuilder.buildOriginalTransformer(); + String output1 = transformer1.transform(EVENT); + Assertions.assertEquals(EVENT, output1); + } + + @Test + public void testConstantTransformer() throws JsonProcessingException { + TransformerParam transformerParam = new TransformerParam(TransformerType.CONSTANT, "constant test"); + Transformer transformer = TransformerBuilder.buildTransformer(transformerParam); + String output = transformer.transform(EVENT); + Assertions.assertEquals("constant test", output); + + Transformer transformer1 = TransformerBuilder.buildConstantTransformer("constant test"); + String output1 = transformer1.transform(EVENT); + Assertions.assertEquals("constant test", output1); + + } + + @Test + public void testTemplateTransFormerWithStringValue() throws JsonProcessingException { + String content = "{\"data-name\":\"$.data.name\"}"; + String template = "Transformers test:data name is ${data-name}"; + Transformer transform = TransformerBuilder.buildTemplateTransFormer(content, template); + String output = transform.transform(EVENT); + Assertions.assertEquals("Transformers test:data name is test-transformer", output); + + TransformerParam transformerParam = new TransformerParam(TransformerType.TEMPLATE, content, template); + + Transformer transformer1 = TransformerBuilder.buildTransformer(transformerParam); + String output1 = transformer1.transform(EVENT); + Assertions.assertEquals("Transformers test:data name is test-transformer", output1); + + } + + @Test + public void testTemplateTransFormerWithNullContent() throws JsonProcessingException { + String content = "{}"; + String template = "Transformers test:data num is ${data-num}"; + Transformer transformer = TransformerBuilder.buildTemplateTransFormer(content, template); + String output = transformer.transform(EVENT); + Assertions.assertEquals("Transformers test:data num is ${data-num}", output); + } + + @Test + public void testTemplateTransFormerWithNoMatchContent() throws JsonProcessingException { + String extractJson = "{\"data-num\":\"$.data.no\"}"; + String template = "Transformers test:data num is ${data-num}"; + Transformer transformer = TransformerBuilder.buildTemplateTransFormer(extractJson, template); + String output = transformer.transform(EVENT); + Assertions.assertEquals("Transformers test:data num is null", output); + } + + @Test + public void testTemplateTransFormerWithMatchNumValue() throws JsonProcessingException { + String extractJson = "{\"data-num\":\"$.data.num\"}"; + String template = "Transformers test:data num is ${data-num}"; + Transformer transformer = TransformerBuilder.buildTemplateTransFormer(extractJson, template); + String output = transformer.transform(EVENT); + Assertions.assertEquals("Transformers test:data num is 100", output); + } + + @Test + public void testTemplateTransFormerWithMatchNullValue() throws JsonProcessingException { + String content = "{\"data-null\":\"$.data.nullV\"}"; + String template = "Transformers test:data null is ${data-null}"; + Transformer transformer = TransformerBuilder.buildTemplateTransFormer(content, template); + String output = transformer.transform(EVENT); + Assertions.assertEquals("Transformers test:data null is null", output); + } + + @Test + public void testTemplateTransFormerWithMatchBooleanValue() throws JsonProcessingException { + String extractJson = "{\"boolean\":\"$.data.boolean\"}"; + String template = "Transformers test:data boolean is ${boolean}"; + Transformer transformer = TransformerBuilder.buildTemplateTransFormer(extractJson, template); + String output = transformer.transform(EVENT); + Assertions.assertEquals("Transformers test:data boolean is true", output); + } + + // + @Test + public void testTemplateTransFormerWithConstant() throws JsonProcessingException { + String extractJson = "{\"name\":\"$.data.name\",\"constant\":\"constant\"" + "}"; + String template = "Transformers test:data name is ${name}, constant is ${constant}"; + Transformer transformer = TransformerBuilder.buildTemplateTransFormer(extractJson, template); + String output = transformer.transform(EVENT); + Assertions.assertEquals("Transformers test:data name is test-transformer, constant is constant", + output); + } + +} diff --git a/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManager.java b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManager.java index 5b4ad167b1..df06ce9875 100644 --- a/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManager.java +++ b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManager.java @@ -32,12 +32,10 @@ import lombok.extern.slf4j.Slf4j; - @Slf4j public class AdminWebHookConfigOperationManager { - private static final transient Map> WEBHOOK_CONFIG_OPERATION_MAP - = new HashMap<>(); + private static final Map> WEBHOOK_CONFIG_OPERATION_MAP = new HashMap<>(); static { WEBHOOK_CONFIG_OPERATION_MAP.put(OPERATION_MODE_FILE, FileWebHookConfigOperation.class); @@ -65,18 +63,20 @@ public void init() throws InvocationTargetException, InstantiationException, Ill throw new IllegalStateException("operationMode is not supported."); } + // Affects which implementation of the WebHookConfigOperation interface is used. final Constructor constructor = WEBHOOK_CONFIG_OPERATION_MAP.get(operationMode).getDeclaredConstructor(Properties.class); - final boolean oldAccesssible = constructor.isAccessible(); + // Save the original accessibility of constructor + final boolean oldAccessible = constructor.isAccessible(); try { constructor.setAccessible(true); final Properties operationProperties = adminConfiguration.getOperationProperties(); - if (log.isInfoEnabled()) { - log.info("operationMode is {} properties is {} ", operationMode, operationProperties); - } + + log.info("operationMode is {} properties is {} ", operationMode, operationProperties); this.webHookConfigOperation = constructor.newInstance(operationProperties); } finally { - constructor.setAccessible(oldAccesssible); + // Restore the original accessibility of constructor + constructor.setAccessible(oldAccessible); } } 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 index b9a8d6d960..1d1ce1309f 100644 --- 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 @@ -21,6 +21,7 @@ import org.apache.eventmesh.webhook.api.WebHookConfig; import org.apache.eventmesh.webhook.api.WebHookConfigOperation; import org.apache.eventmesh.webhook.api.WebHookOperationConstant; +import org.apache.eventmesh.webhook.api.common.SharedLatchHolder; import org.apache.eventmesh.webhook.api.utils.ClassUtils; import java.io.BufferedReader; @@ -61,10 +62,7 @@ public FileWebHookConfigOperation(final Properties properties) throws FileNotFou @Override public Integer insertWebHookConfig(final WebHookConfig webHookConfig) { if (!webHookConfig.getCallbackPath().startsWith(WebHookOperationConstant.CALLBACK_PATH_PREFIX)) { - if (log.isErrorEnabled()) { - log.error("webhookConfig callback path must start with {}", - WebHookOperationConstant.CALLBACK_PATH_PREFIX); - } + log.error("webhookConfig callback path must start with {}", WebHookOperationConstant.CALLBACK_PATH_PREFIX); return 0; } @@ -75,9 +73,7 @@ public Integer insertWebHookConfig(final WebHookConfig webHookConfig) { final File webhookConfigFile = getWebhookConfigFile(webHookConfig); if (webhookConfigFile.exists()) { - if (log.isErrorEnabled()) { - log.error("webhookConfig {} is existed", webHookConfig.getCallbackPath()); - } + log.error("webhookConfig {} exists", webHookConfig.getCallbackPath()); return 0; } return writeToFile(webhookConfigFile, webHookConfig) ? 1 : 0; @@ -87,9 +83,7 @@ public Integer insertWebHookConfig(final WebHookConfig webHookConfig) { public Integer updateWebHookConfig(final WebHookConfig webHookConfig) { final File webhookConfigFile = getWebhookConfigFile(webHookConfig); if (!webhookConfigFile.exists()) { - if (log.isErrorEnabled()) { - log.error("webhookConfig {} is not existed", webHookConfig.getCallbackPath()); - } + log.error("webhookConfig {} does not exist", webHookConfig.getCallbackPath()); return 0; } return writeToFile(webhookConfigFile, webHookConfig) ? 1 : 0; @@ -97,23 +91,24 @@ public Integer updateWebHookConfig(final WebHookConfig webHookConfig) { @Override public Integer deleteWebHookConfig(final WebHookConfig webHookConfig) { - final File webhookConfigFile = getWebhookConfigFile(webHookConfig); - if (!webhookConfigFile.exists()) { - if (log.isErrorEnabled()) { - log.error("webhookConfig {} is not existed", webHookConfig.getCallbackPath()); + synchronized (SharedLatchHolder.lock) { + final File webhookConfigFile = getWebhookConfigFile(webHookConfig); + if (!webhookConfigFile.exists()) { + log.error("webhookConfig {} does not exist", webHookConfig.getCallbackPath()); + return 0; } - return 0; + return webhookConfigFile.delete() ? 1 : 0; } - return webhookConfigFile.delete() ? 1 : 0; } + /** + * Query WebHook configuration information based on the WebHook callback path specified in {@link WebHookConfig}. + */ @Override public WebHookConfig queryWebHookConfigById(final WebHookConfig webHookConfig) { final File webhookConfigFile = getWebhookConfigFile(webHookConfig); if (!webhookConfigFile.exists()) { - if (log.isErrorEnabled()) { - log.error("webhookConfig {} is not existed", webHookConfig.getCallbackPath()); - } + log.error("webhookConfig {} does not exist", webHookConfig.getCallbackPath()); return null; } @@ -127,9 +122,7 @@ public List queryWebHookConfigByManufacturer(final WebHookConfig final String manuDirPath = getWebhookConfigManuDir(webHookConfig); final File manuDir = new File(manuDirPath); if (!manuDir.exists()) { - if (log.isWarnEnabled()) { - log.warn("webhookConfig dir {} is not existed", manuDirPath); - } + log.warn("webhookConfig dir {} does not exist", manuDirPath); return new ArrayList<>(); } @@ -160,9 +153,7 @@ private WebHookConfig getWebHookConfigFromFile(final File webhookConfigFile) { fileContent.append(line); } } catch (IOException e) { - if (log.isErrorEnabled()) { - log.error("get webhook from file {} error", webhookConfigFile.getPath(), e); - } + log.error("get webHookConfig from file {} error", webhookConfigFile.getPath(), e); return null; } @@ -170,18 +161,19 @@ private WebHookConfig getWebHookConfigFromFile(final File webhookConfigFile) { } public static boolean writeToFile(final File webhookConfigFile, final WebHookConfig webHookConfig) { - try (FileOutputStream fos = new FileOutputStream(webhookConfigFile); - BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos, StandardCharsets.UTF_8))) { - // lock this file, and will auto release after fos close - fos.getChannel().lock(); - bw.write(Objects.requireNonNull(JsonUtils.toJSONString(webHookConfig))); - } catch (IOException e) { - if (log.isErrorEnabled()) { + // Wait for the previous cacheInit to complete in case of concurrency + synchronized (SharedLatchHolder.lock) { + try (FileOutputStream fos = new FileOutputStream(webhookConfigFile); + BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos, StandardCharsets.UTF_8))) { + // Lock this file to prevent concurrent modification and it will be automatically unlocked when fos closes + fos.getChannel().lock(); + bw.write(Objects.requireNonNull(JsonUtils.toJSONString(webHookConfig))); + } catch (IOException e) { log.error("write webhookConfig {} to file error", webHookConfig.getCallbackPath()); + return false; } - return false; + return true; } - return true; } private String getWebhookConfigManuDir(final WebHookConfig webHookConfig) { 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 index 4af4500d7e..f6c9667dd9 100644 --- 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 @@ -28,9 +28,6 @@ import org.apache.eventmesh.webhook.api.WebHookConfigOperation; import org.apache.eventmesh.webhook.api.WebHookOperationConstant; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -43,7 +40,6 @@ import lombok.extern.slf4j.Slf4j; - @Slf4j public class NacosWebHookConfigOperation implements WebHookConfigOperation { @@ -51,7 +47,6 @@ public class NacosWebHookConfigOperation implements WebHookConfigOperation { private final ConfigService configService; - public NacosWebHookConfigOperation(final Properties properties) throws NacosException { configService = ConfigFactory.createConfigService(properties); @@ -66,10 +61,7 @@ public NacosWebHookConfigOperation(final Properties properties) throws NacosExce @Override public Integer insertWebHookConfig(final WebHookConfig webHookConfig) { if (!webHookConfig.getCallbackPath().startsWith(WebHookOperationConstant.CALLBACK_PATH_PREFIX)) { - if (log.isErrorEnabled()) { - log.error("webhookConfig callback path must start with {}", - WebHookOperationConstant.CALLBACK_PATH_PREFIX); - } + log.error("webhookConfig callback path must start with {}", WebHookOperationConstant.CALLBACK_PATH_PREFIX); return 0; } @@ -78,9 +70,7 @@ public Integer insertWebHookConfig(final WebHookConfig webHookConfig) { try { if (configService.getConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig), TIMEOUT_MS) != null) { - if (log.isErrorEnabled()) { - log.error("insertWebHookConfig failed, config has existed"); - } + log.error("insertWebHookConfig failed, config has existed"); return 0; } result = configService.publishConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig), @@ -100,7 +90,7 @@ public Integer insertWebHookConfig(final WebHookConfig webHookConfig) { JsonUtils.toJSONString(manufacturer), ConfigType.JSON.getType()); } catch (NacosException e) { log.error("update manufacturersInfo error", e); - //rollback insert + // rollback insert try { configService.removeConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig)); } catch (NacosException ex) { @@ -117,9 +107,7 @@ public Integer updateWebHookConfig(final WebHookConfig webHookConfig) { try { if (configService.getConfig(getWebHookConfigDataId(webHookConfig), getManuGroupId(webHookConfig), TIMEOUT_MS) == null) { - if (log.isErrorEnabled()) { - log.error("updateWebHookConfig failed, config is not existed"); - } + log.error("updateWebHookConfig failed, config is not existed"); return 0; } result = configService.publishConfig(getWebHookConfigDataId(webHookConfig), @@ -153,6 +141,9 @@ public Integer deleteWebHookConfig(final WebHookConfig webHookConfig) { return result ? 1 : 0; } + /** + * Query WebHook configuration information based on the WebHook callback path specified in {@link WebHookConfig}. + */ @Override public WebHookConfig queryWebHookConfigById(final WebHookConfig webHookConfig) { try { @@ -192,19 +183,16 @@ public List queryWebHookConfigByManufacturer(final WebHookConfig } /** - * @param webHookConfig - * @return + * Escape callback path to a valid dataId. */ private String getWebHookConfigDataId(final 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(), StandardCharsets.UTF_8.name()) + DATA_ID_EXTENSION; - } catch (UnsupportedEncodingException e) { - if (log.isErrorEnabled()) { - log.error("get webhookConfig dataId {} failed", webHookConfig.getCallbackPath(), e); - } + String dataId = webHookConfig.getCallbackPath(); + if (dataId.startsWith("/")) { + // remove the first slash + dataId = dataId.substring(1); } - return webHookConfig.getCallbackPath() + DATA_ID_EXTENSION; + // then replace the subsequent invalid chars with dots + return dataId.replaceAll("[@#$%^&*,/\\\\]", ".") + DATA_ID_EXTENSION; } private String getManuGroupId(final WebHookConfig webHookConfig) { @@ -214,7 +202,8 @@ private String getManuGroupId(final WebHookConfig webHookConfig) { private Manufacturer getManufacturersInfo() throws NacosException { final String manufacturersContent = configService.getConfig(MANUFACTURERS_DATA_ID, CONSTANTS_WEBHOOK, TIMEOUT_MS); return StringUtil.isNullOrEmpty(manufacturersContent) - ? new Manufacturer() : JsonUtils.parseObject(manufacturersContent, Manufacturer.class); + ? new Manufacturer() + : JsonUtils.parseObject(manufacturersContent, Manufacturer.class); } } diff --git a/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/config/AdminConfiguration.java b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/config/AdminConfiguration.java index 1afecc78c7..93327d54bf 100644 --- a/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/config/AdminConfiguration.java +++ b/eventmesh-webhook/eventmesh-webhook-admin/src/main/java/org/apache/eventmesh/webhook/config/AdminConfiguration.java @@ -46,4 +46,3 @@ public void processOperationProperties() { this.operationProperties = (Properties) operationProperties.get(prefix); } } - diff --git a/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManagerTest.java b/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManagerTest.java index 1396178087..6eabd2f313 100644 --- a/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManagerTest.java +++ b/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/admin/AdminWebHookConfigOperationManagerTest.java @@ -19,8 +19,8 @@ import org.apache.eventmesh.common.config.ConfigService; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class AdminWebHookConfigOperationManagerTest { @@ -32,7 +32,7 @@ public void init() throws Exception { AdminWebHookConfigOperationManager adminWebHookConfigOperationManage = new AdminWebHookConfigOperationManager(); adminWebHookConfigOperationManage.init(); - Assert.assertTrue( + Assertions.assertTrue( adminWebHookConfigOperationManage.getWebHookConfigOperation() instanceof FileWebHookConfigOperation); } } diff --git a/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/admin/FileWebHookConfigOperationTest.java b/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/admin/FileWebHookConfigOperationTest.java index 0c6450fb78..2179341557 100644 --- a/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/admin/FileWebHookConfigOperationTest.java +++ b/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/admin/FileWebHookConfigOperationTest.java @@ -28,37 +28,34 @@ import java.util.Objects; import java.util.Properties; -import org.junit.Assert; -import org.junit.Test; - +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class FileWebHookConfigOperationTest { @Test - public void testInsertWebHookConfig() { + public void testInsertWebHookConfig() throws Exception { Properties properties = new Properties(); properties.setProperty("filePath", "test_dir"); WebHookConfig config = new WebHookConfig(); config.setCallbackPath("/webhook/github/eventmesh/all"); config.setManufacturerName("github"); + config.setManufacturerDomain("www.github.com"); config.setManufacturerEventName("all"); config.setSecret("eventmesh"); config.setCloudEventName("github-eventmesh"); - config.setCloudEventSource("github"); try { FileWebHookConfigOperation fileWebHookConfigOperation = new FileWebHookConfigOperation(properties); Integer result = fileWebHookConfigOperation.insertWebHookConfig(config); - Assert.assertTrue(Objects.nonNull(result) && result == 1); + Assertions.assertTrue(Objects.nonNull(result) && result == 1); WebHookConfig queryConfig = new WebHookConfig(); queryConfig.setManufacturerName("github"); List queryResult = fileWebHookConfigOperation.queryWebHookConfigByManufacturer(queryConfig, 1, 1); - Assert.assertTrue(Objects.nonNull(queryResult) && queryResult.size() == 1); - Assert.assertEquals(queryResult.get(0).getCallbackPath(), config.getCallbackPath()); - } catch (Exception e) { - Assert.fail(e.getMessage()); + Assertions.assertTrue(Objects.nonNull(queryResult) && queryResult.size() == 1); + Assertions.assertEquals(queryResult.get(0).getCallbackPath(), config.getCallbackPath()); } finally { deleteDir("test_dir"); } diff --git a/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/config/AdminConfigurationTest.java b/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/config/AdminConfigurationTest.java index 34e88c96fd..54a2e98ac1 100644 --- a/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/config/AdminConfigurationTest.java +++ b/eventmesh-webhook/eventmesh-webhook-admin/src/test/java/org/apache/eventmesh/webhook/config/AdminConfigurationTest.java @@ -21,8 +21,8 @@ import java.util.Properties; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class AdminConfigurationTest { @@ -38,11 +38,11 @@ public void testGetAdminConfiguration() throws Exception { } private void assertAdminConfiguration(AdminConfiguration config) { - Assert.assertTrue(config.isAdminStart()); - Assert.assertEquals("file", config.getOperationMode()); + Assertions.assertTrue(config.isAdminStart()); + Assertions.assertEquals("file", config.getOperationMode()); Properties properties = new Properties(); properties.put("filePath", "."); - Assert.assertEquals(properties, config.getOperationProperties()); + Assertions.assertEquals(properties, config.getOperationProperties()); } -} \ No newline at end of file +} diff --git a/eventmesh-webhook/eventmesh-webhook-admin/src/test/resources/eventmesh.properties b/eventmesh-webhook/eventmesh-webhook-admin/src/test/resources/eventmesh.properties index cbf4371d87..b808436f97 100644 --- a/eventmesh-webhook/eventmesh-webhook-admin/src/test/resources/eventmesh.properties +++ b/eventmesh-webhook/eventmesh-webhook-admin/src/test/resources/eventmesh.properties @@ -24,5 +24,5 @@ eventMesh.webHook.fileMode.filePath=. # 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 storage. plugin. The type configuration is the same +# Webhook CloudEvent sending mode. This property is the same as the eventMesh.storage.plugin.type configuration. eventMesh.webHook.producer.storage=standalone diff --git a/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/Manufacturer.java b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/Manufacturer.java index 53f175712b..6573c8e258 100644 --- a/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/Manufacturer.java +++ b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/Manufacturer.java @@ -30,7 +30,6 @@ public class Manufacturer { private Map> manufacturerEventMap = new ConcurrentHashMap<>(); - public Set getManufacturerSet() { return manufacturerSet; } 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 index 9989a4862d..3f1d26c876 100644 --- 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 @@ -28,12 +28,17 @@ public class WebHookConfig { private String callbackPath; /** - * manufacturer name ,like github + * manufacturer name, like github */ private String manufacturerName; /** - * webhook event name ,like rep-push + * manufacturer domain name, like www.github.com + */ + private String manufacturerDomain; + + /** + * webhook event name, like rep-push */ private String manufacturerEventName; @@ -48,22 +53,22 @@ public class WebHookConfig { private String description; /** - * secret key ,for authentication + * secret key, for authentication */ private String secret; /** - * userName ,for HTTP authentication + * userName, for HTTP authentication */ private String userName; /** - * password ,for HTTP authentication + * password, for HTTP authentication */ private String password; /** - * roll out protocol ,like http/kafka + * roll out protocol, like HTTP/Kafka */ private String cloudEventProtocol; @@ -73,7 +78,7 @@ public class WebHookConfig { private String cloudEventServiceAddress; /** - * roll out event name ,like topic to mq + * roll out event name, like topic to MQ */ private String cloudEventName; @@ -83,12 +88,7 @@ public class WebHookConfig { private String dataContentType = "application/json"; /** - * source of event - */ - private String cloudEventSource; - - /** - * id of cloudEvent ,like uuid/manufacturerEventId + * 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 index fbe2700885..e7f3fbc20d 100644 --- 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 @@ -20,7 +20,16 @@ import java.util.List; /** - * WebHookConfigOperation + * This interface has three implementation classes, among which + * {@code FileWebHookConfigOperation} and {@code NacosWebHookConfigOperation} + * serve the {@code /webhook/deleteWebHookConfig} endpoint. + *

+ * They correspond to the persistent configuration of {@linkplain org.apache.eventmesh.webhook.api.WebHookConfig WebHookConfig} + * for {@code file} and {@code Nacos}, respectively. + *

+ * However, the {@code HookConfigOperationManager}, which is located in the {@code org.apache.eventmesh.webhook.receive.storage} + * package, differs from the other two implementations which are located in the {@code org.apache.eventmesh.webhook.admin} + * package. Refer to {@code QueryWebHookConfigByIdHandler} for the reasons and details. */ public interface WebHookConfigOperation { diff --git a/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/common/SharedLatchHolder.java b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/common/SharedLatchHolder.java new file mode 100644 index 0000000000..c59ff54b31 --- /dev/null +++ b/eventmesh-webhook/eventmesh-webhook-api/src/main/java/org/apache/eventmesh/webhook/api/common/SharedLatchHolder.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.webhook.api.common; + +public class SharedLatchHolder { + + // secure the execution sequence of writeToFile and cacheInit + public static final Object lock = new Object(); + +} 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 index b86f0c91b7..5f67307d7a 100644 --- 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 @@ -28,7 +28,6 @@ public interface ManufacturerProtocol { String getManufacturerName(); - /** * - 1.authentication - 2.parse webhook content to WebHookRequest * 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 index 6e672a3db8..217a3720b3 100644 --- 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 @@ -23,6 +23,7 @@ import org.apache.eventmesh.common.config.ConfigService; import org.apache.eventmesh.common.protocol.ProtocolTransportObject; import org.apache.eventmesh.common.protocol.http.WebhookProtocolTransportObject; +import org.apache.eventmesh.common.utils.LogUtil; import org.apache.eventmesh.protocol.api.ProtocolAdaptor; import org.apache.eventmesh.protocol.api.ProtocolPluginFactory; import org.apache.eventmesh.webhook.api.WebHookConfig; @@ -79,6 +80,7 @@ public void init() throws Exception { * @param path CallbackPath * @param header map of webhook request header * @param body data + * @throws Exception if any uncaught exception occurs during execution */ public void execute(String path, Map header, byte[] body) throws Exception { @@ -113,23 +115,20 @@ public void execute(String path, Map header, byte[] body) throws WebhookProtocolTransportObject webhookProtocolTransportObject = WebhookProtocolTransportObject.builder() .cloudEventId(cloudEventId).eventType(eventType).cloudEventName(webHookConfig.getCloudEventName()) - .cloudEventSource("www." + webHookConfig.getManufacturerName() + ".com") + .cloudEventSource(webHookConfig.getManufacturerDomain()) .dataContentType(webHookConfig.getDataContentType()).body(body).build(); // 4. send cloudEvent webHookMQProducer.send(this.protocolAdaptor.toCloudEvent(webhookProtocolTransportObject), new SendCallback() { + @Override public void onSuccess(SendResult sendResult) { - if (log.isDebugEnabled()) { - log.debug(sendResult.toString()); - } + LogUtil.debug(log, "{}", sendResult::toString); } @Override public void onException(OnExceptionContext context) { - if (log.isWarnEnabled()) { - log.warn("", context.getException()); - } + log.warn("", context.getException()); } }); 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 index 63d0839204..ce6fa22fe5 100644 --- 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 @@ -17,7 +17,6 @@ package org.apache.eventmesh.webhook.receive.protocol; - import org.apache.eventmesh.common.Constants; import org.apache.eventmesh.webhook.api.WebHookConfig; import org.apache.eventmesh.webhook.receive.ManufacturerProtocol; diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/HookConfigOperationManager.java b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/HookConfigOperationManager.java index bb1641596e..d700715d9d 100644 --- a/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/HookConfigOperationManager.java +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/main/java/org/apache/eventmesh/webhook/receive/storage/HookConfigOperationManager.java @@ -29,7 +29,6 @@ import org.apache.eventmesh.webhook.api.utils.ClassUtils; import org.apache.eventmesh.webhook.receive.config.ReceiveConfiguration; -import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -42,6 +41,17 @@ import lombok.extern.slf4j.Slf4j; +/** + * This class manages the operations related to WebHook configurations. Mainly used by + * {@linkplain org.apache.eventmesh.webhook.receive.WebHookController#execute WebHookController} + * to retrieve existing WebHook configuration by callback path when processing received WebHook data from manufacturers. + *

+ * This class is initialized together with the {@linkplain org.apache.eventmesh.webhook.receive.WebHookController WebHookController} + * during the initialization phase of the {@code EventMeshHTTPServer}. + * + * @see WebHookConfigOperation + */ + @Slf4j public class HookConfigOperationManager implements WebHookConfigOperation { @@ -56,19 +66,28 @@ public HookConfigOperationManager() { } /** - * Initialize according to operationMode + * Initialize according to operation mode. + *

+ * OPERATION_MODE_FILE: The WebHook configurations are read from a file specified by the filePath. + * OPERATION_MODE_NACOS: The WebHook configurations are fetched from a Nacos configuration service + * using the properties specified in operationProperties. * - * @param receiveConfiguration receiveConfiguration + * @param receiveConfiguration The ReceiveConfiguration object containing the operation mode and related properties. + * @throws NacosException If there is an error with the Nacos configuration service. */ - public HookConfigOperationManager(final ReceiveConfiguration receiveConfiguration) - throws FileNotFoundException, NacosException { + public HookConfigOperationManager(final ReceiveConfiguration receiveConfiguration) throws NacosException { this.operationMode = receiveConfiguration.getOperationMode(); - if (OPERATION_MODE_FILE.equals(operationMode)) { - new WebhookFileListener(receiveConfiguration.getFilePath(), cacheWebHookConfig); - } else if (OPERATION_MODE_NACOS.equals(operationMode)) { - nacosModeInit(receiveConfiguration.getOperationProperties()); + switch (operationMode) { + case OPERATION_MODE_FILE: + new WebhookFileListener(receiveConfiguration.getFilePath(), cacheWebHookConfig); + break; + case OPERATION_MODE_NACOS: + nacosModeInit(receiveConfiguration.getOperationProperties()); + break; + default: + break; } } @@ -76,23 +95,43 @@ private void nacosModeInit(final Properties config) throws NacosException { nacosConfigService = ConfigFactory.createConfigService(config); } + /** + * Retrieves a WebHook configuration according to its WebHook callback path in + * {@linkplain org.apache.eventmesh.webhook.api.WebHookConfig WebHookConfig}. + * + * @param webHookConfig The WebHookConfig object containing the callback path. + * @return The retrieved WebHookConfig object which contains full configuration. + */ @Override public WebHookConfig queryWebHookConfigById(final WebHookConfig webHookConfig) { - if (OPERATION_MODE_FILE.equals(operationMode)) { - return cacheWebHookConfig.get(ClassUtils.convertResourcePathToClassName(webHookConfig.getCallbackPath())); - } else if (OPERATION_MODE_NACOS.equals(operationMode)) { - try { - final String content = nacosConfigService.getConfig(webHookConfig.getManufacturerEventName() - + DATA_ID_EXTENSION, - GROUP_PREFIX + webHookConfig.getManufacturerName(), TIMEOUT_MS); - return JsonUtils.parseObject(content, WebHookConfig.class); - } catch (NacosException e) { - log.error("queryWebHookConfigById failed", e); - } + switch (operationMode) { + case OPERATION_MODE_FILE: + return cacheWebHookConfig.get(ClassUtils.convertResourcePathToClassName(webHookConfig.getCallbackPath())); + case OPERATION_MODE_NACOS: + try { + final String content = nacosConfigService.getConfig( + webHookConfig.getManufacturerEventName() + DATA_ID_EXTENSION, + GROUP_PREFIX + webHookConfig.getManufacturerName(), + TIMEOUT_MS); + return JsonUtils.parseObject(content, WebHookConfig.class); + } catch (NacosException e) { + log.error("queryWebHookConfigById failed", e); + } + break; + default: + break; } return null; } + /** + * Retrieves a list of WebHook configurations for a specific manufacturer. + * + * @param webHookConfig The WebHookConfig object containing the manufacturer name. + * @param pageNum The page number for pagination. + * @param pageSize The page size for pagination. + * @return The list of WebHookConfig objects which each contains full configuration. + */ @Override public List queryWebHookConfigByManufacturer(final WebHookConfig webHookConfig, final Integer pageNum, @@ -100,18 +139,36 @@ public List queryWebHookConfigByManufacturer(final WebHookConfig return new ArrayList(); } + /** + * Inserts a new WebHook configuration into the cache. + * + * @param webHookConfig The WebHookConfig object to insert. + * @return The result code indicating the success of the operation. + */ @Override public Integer insertWebHookConfig(final WebHookConfig webHookConfig) { cacheWebHookConfig.put(webHookConfig.getCallbackPath(), webHookConfig); return 1; } + /** + * Updates an existing WebHook configuration in the cache. + * + * @param webHookConfig The WebHookConfig object to update. + * @return The result code indicating the success of the operation. + */ @Override public Integer updateWebHookConfig(final WebHookConfig webHookConfig) { cacheWebHookConfig.put(webHookConfig.getCallbackPath(), webHookConfig); return 1; } + /** + * Deletes a WebHook configuration from the cache. + * + * @param webHookConfig The WebHookConfig object to delete. + * @return The result code indicating the success of the operation. + */ @Override public Integer deleteWebHookConfig(final WebHookConfig webHookConfig) { cacheWebHookConfig.remove(webHookConfig.getCallbackPath()); 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 index 5461cdcbb2..e5af8501b5 100644 --- 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 @@ -24,6 +24,7 @@ import org.apache.eventmesh.common.utils.JsonUtils; import org.apache.eventmesh.webhook.api.WebHookConfig; import org.apache.eventmesh.webhook.api.WebHookOperationConstant; +import org.apache.eventmesh.webhook.api.common.SharedLatchHolder; import java.io.BufferedReader; import java.io.File; @@ -51,7 +52,7 @@ public class WebhookFileListener { private final transient Set pathSet = new LinkedHashSet<>(); // monitored subdirectory private final transient Map watchKeyPathMap = new ConcurrentHashMap<>(); // WatchKey's path private transient String filePath; - private transient Map cacheWebHookConfig; + private final transient Map cacheWebHookConfig; public WebhookFileListener(final String filePath, final Map cacheWebHookConfig) { this.filePath = WebHookOperationConstant.getFilePath(filePath); @@ -90,20 +91,21 @@ private void readFiles(final File file) { } /** - * Read the file and cache it in map + * Read the file and cache it in local map for manufacturers webhook payload delivery + *

+ * A shared lock is used to ensure that this method should be invoked after the {@code webhookConfigFile} is written completely + * by {@code org.apache.eventmesh.webhook.admin.FileWebHookConfigOperation#writeToFile} when multiple modify events are triggered. * * @param webhookConfigFile webhookConfigFile */ private void cacheInit(final File webhookConfigFile) { final StringBuilder fileContent = new StringBuilder(); - try (BufferedReader br = Files.newBufferedReader(Paths.get(webhookConfigFile.getAbsolutePath()), - StandardCharsets.UTF_8)) { + try (BufferedReader br = Files.newBufferedReader(Paths.get(webhookConfigFile.getAbsolutePath()), StandardCharsets.UTF_8)) { while (br.ready()) { fileContent.append(br.readLine()); } - } catch (IOException e) { - log.error("cacheInit failed", e); + log.error("cacheInit buffer read failed", e); } final WebHookConfig webHookConfig = JsonUtils.parseObject(fileContent.toString(), WebHookConfig.class); cacheWebHookConfig.put(webhookConfigFile.getName(), webHookConfig); @@ -143,36 +145,47 @@ private void fileWatchRegister() { WatchKey key = null; try { assert service != null; + // The code will block here until a file system event occurs key = service.take(); } catch (InterruptedException e) { log.error("Interrupted", e); + Thread.currentThread().interrupt(); } assert key != null; + // A newly created config file will be captured for two events, ENTRY_CREATE and ENTRY_MODIFY for (final WatchEvent event : key.pollEvents()) { final String flashPath = watchKeyPathMap.get(key); // manufacturer change - final String path = flashPath.concat("/").concat(event.context().toString()); + final String path = flashPath.concat(WebHookOperationConstant.FILE_SEPARATOR).concat(event.context().toString()); final File file = new File(path); - if (ENTRY_CREATE == event.kind() || ENTRY_MODIFY == event.kind()) { - if (file.isFile()) { - cacheInit(file); - } else { + // Wait for file write/delete completion before initializing the cache + synchronized (SharedLatchHolder.lock) { + if (file.isDirectory() && (ENTRY_CREATE == event.kind() || ENTRY_MODIFY == event.kind())) { + // If it is a folder, re-register the listener try { key = Paths.get(path).register(service, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE); watchKeyPathMap.put(key, path); } catch (IOException e) { log.error("registerWatchKey failed", e); } - } - } else if (ENTRY_DELETE == event.kind()) { - if (file.isDirectory()) { - watchKeyPathMap.remove(key); - } else { - deleteConfig(file); + } else if (file.isFile() && ENTRY_MODIFY == event.kind()) { + // If it is a file, cache it only when it is modified to wait for complete file writes + try { + cacheInit(file); + } catch (Exception e) { + log.error("cacheInit failed", e); + } + } else if (ENTRY_DELETE == event.kind()) { + if (file.isDirectory()) { + watchKeyPathMap.remove(key); + } else { + deleteConfig(file); + } } } } + // Reset the WatchKey to receive subsequent file system events if (!key.reset()) { break; } diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/test/java/org/apache/eventmesh/webhook/receive/config/ReceiveConfigurationTest.java b/eventmesh-webhook/eventmesh-webhook-receive/src/test/java/org/apache/eventmesh/webhook/receive/config/ReceiveConfigurationTest.java index b4a6127863..1b1390dfb9 100644 --- a/eventmesh-webhook/eventmesh-webhook-receive/src/test/java/org/apache/eventmesh/webhook/receive/config/ReceiveConfigurationTest.java +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/test/java/org/apache/eventmesh/webhook/receive/config/ReceiveConfigurationTest.java @@ -21,8 +21,8 @@ import java.util.Properties; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class ReceiveConfigurationTest { @@ -33,19 +33,19 @@ public void testGetReceiveConfiguration() throws Exception { configService.setRootConfig("classPath://eventmesh.properties"); Properties rootConfig = ConfigService.getInstance().getRootConfig(); - Assert.assertEquals("DEFAULT", rootConfig.get("eventMesh.server.idc")); + Assertions.assertEquals("DEFAULT", rootConfig.get("eventMesh.server.idc")); ReceiveConfiguration config = configService.buildConfigInstance(ReceiveConfiguration.class); assertReceiveConfiguration(config); } private void assertReceiveConfiguration(ReceiveConfiguration config) { - Assert.assertEquals("nacos", config.getOperationMode()); + Assertions.assertEquals("nacos", config.getOperationMode()); Properties properties = new Properties(); properties.put("serverAddr", "127.0.0.1:8848"); - Assert.assertEquals(properties, config.getOperationProperties()); - Assert.assertEquals("standalone", config.getStoragePluginType()); - Assert.assertEquals(".", config.getFilePath()); + Assertions.assertEquals(properties, config.getOperationProperties()); + Assertions.assertEquals("standalone", config.getStoragePluginType()); + Assertions.assertEquals(".", config.getFilePath()); } } diff --git a/eventmesh-webhook/eventmesh-webhook-receive/src/test/resources/eventmesh.properties b/eventmesh-webhook/eventmesh-webhook-receive/src/test/resources/eventmesh.properties index 90e359d581..bd700c26c9 100644 --- a/eventmesh-webhook/eventmesh-webhook-receive/src/test/resources/eventmesh.properties +++ b/eventmesh-webhook/eventmesh-webhook-receive/src/test/resources/eventmesh.properties @@ -26,5 +26,5 @@ eventMesh.webHook.fileMode.filePath=. # 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 storage. plugin. The type configuration is the same +# Webhook CloudEvent sending mode. This property is the same as the eventMesh.storage.plugin.type configuration. eventMesh.webHook.producer.storage=standalone diff --git a/gradle.properties b/gradle.properties index 89018bf93f..789424c0de 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,7 +18,7 @@ jdk=1.8 snapshot=false group=org.apache.eventmesh -version=1.8.0-release +version=1.10.0-release #last eight bits of public key signing.keyId= #passphrase for key pairs @@ -32,4 +32,5 @@ apachePassWord= signEnabled=false org.gradle.warning.mode=none -org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +org.gradle.caching=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2a..033e24c4cd 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 7e9c8c73d3..2b303b2bb5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -17,6 +17,8 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index b20efadc69..fcb6fca147 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/bin/sh # # Copyright © 2015-2021 the original authors. @@ -55,7 +55,7 @@ # 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 +# https://github.com/gradle/gradle/blob/HEAD/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/. @@ -63,61 +63,52 @@ ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MSYS* | MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -127,9 +118,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -138,88 +129,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -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 - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 477c896641..93e3f59f13 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,15 +76,17 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal -:omega \ No newline at end of file +:omega diff --git a/resources/eventmesh-architecture-4.png b/resources/eventmesh-architecture-4.png index c675fb1381..9ab4a750a0 100644 Binary files a/resources/eventmesh-architecture-4.png and b/resources/eventmesh-architecture-4.png differ diff --git a/settings.gradle b/settings.gradle index 1b3d762862..645e6fb365 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,6 +15,33 @@ * limitations under the License. */ +plugins { + id 'com.gradle.enterprise' version '3.16.1' + id 'com.gradle.common-custom-user-data-gradle-plugin' version '1.12.1' +} + +def isCiServer = System.getenv().containsKey("CI") + +gradleEnterprise { + server = "https://ge.apache.org" + buildScan { + capture { taskInputFiles = true } + uploadInBackground = !isCiServer + publishAlways() + publishIfAuthenticated() + obfuscation { + ipAddresses { addresses -> addresses.collect { address -> "0.0.0.0"} } + } + } +} + +buildCache { + remote(gradleEnterprise.buildCache) { + enabled = false + } +} + + rootProject.name = 'eventmesh' String jdkVersion = "${jdk}" include 'eventmesh-runtime' @@ -23,27 +50,54 @@ include 'eventmesh-common' include 'eventmesh-starter' include 'eventmesh-examples' include 'eventmesh-spi' +include 'eventmesh-filter' +include 'eventmesh-transformer' + include 'eventmesh-openconnect:eventmesh-openconnect-java' -include 'eventmesh-connectors:source-connector-rocketmq' -include 'eventmesh-connectors:sink-connector-rocketmq' +include 'eventmesh-openconnect:eventmesh-openconnect-offsetmgmt-plugin:eventmesh-openconnect-offsetmgmt-api' +include 'eventmesh-openconnect:eventmesh-openconnect-offsetmgmt-plugin:eventmesh-openconnect-offsetmgmt-nacos' + +include 'eventmesh-connectors:eventmesh-connector-openfunction' +include 'eventmesh-connectors:eventmesh-connector-rocketmq' +include 'eventmesh-connectors:eventmesh-connector-rabbitmq' +include 'eventmesh-connectors:eventmesh-connector-redis' +include 'eventmesh-connectors:eventmesh-connector-mongodb' +include 'eventmesh-connectors:eventmesh-connector-pulsar' +include 'eventmesh-connectors:eventmesh-connector-kafka' +include 'eventmesh-connectors:eventmesh-connector-s3' +include 'eventmesh-connectors:eventmesh-connector-pravega' +include 'eventmesh-connectors:eventmesh-connector-knative' +include 'eventmesh-connectors:eventmesh-connector-jdbc' +include 'eventmesh-connectors:eventmesh-connector-file' +include 'eventmesh-connectors:eventmesh-connector-spring' +include 'eventmesh-connectors:eventmesh-connector-prometheus' +include 'eventmesh-connectors:eventmesh-connector-dingtalk' +include 'eventmesh-connectors:eventmesh-connector-lark' +include 'eventmesh-connectors:eventmesh-connector-wecom' +include 'eventmesh-connectors:eventmesh-connector-slack' +include 'eventmesh-connectors:eventmesh-connector-wechat' +include 'eventmesh-connectors:eventmesh-connector-http' + include 'eventmesh-storage-plugin:eventmesh-storage-api' include 'eventmesh-storage-plugin:eventmesh-storage-standalone' include 'eventmesh-storage-plugin:eventmesh-storage-kafka' -include 'eventmesh-storage-plugin:eventmesh-storage-knative' -include 'eventmesh-storage-plugin:eventmesh-storage-mongodb' include 'eventmesh-storage-plugin:eventmesh-storage-pulsar' -include 'eventmesh-storage-plugin:eventmesh-storage-pravega' include 'eventmesh-storage-plugin:eventmesh-storage-redis' include 'eventmesh-storage-plugin:eventmesh-storage-rocketmq' include 'eventmesh-storage-plugin:eventmesh-storage-rabbitmq' + +include 'eventmesh-security-plugin' 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-registry-plugin:eventmesh-registry-zookeeper' -include 'eventmesh-admin' +include 'eventmesh-security-plugin:eventmesh-security-auth-http-basic' +include 'eventmesh-security-plugin:eventmesh-security-auth-token' + +include 'eventmesh-meta:eventmesh-meta-api' +include 'eventmesh-meta:eventmesh-meta-nacos' +include 'eventmesh-meta:eventmesh-meta-etcd' +include 'eventmesh-meta:eventmesh-meta-consul' +include 'eventmesh-meta:eventmesh-meta-zookeeper' + include 'eventmesh-protocol-plugin' include 'eventmesh-protocol-plugin:eventmesh-protocol-api' include 'eventmesh-protocol-plugin:eventmesh-protocol-openmessage' @@ -51,27 +105,24 @@ include 'eventmesh-protocol-plugin:eventmesh-protocol-cloudevents' include 'eventmesh-protocol-plugin:eventmesh-protocol-meshmessage' include 'eventmesh-protocol-plugin:eventmesh-protocol-http' include 'eventmesh-protocol-plugin:eventmesh-protocol-webhook' -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-security-plugin:eventmesh-security-auth-token' - include 'eventmesh-trace-plugin' include 'eventmesh-trace-plugin:eventmesh-trace-api' include 'eventmesh-trace-plugin:eventmesh-trace-zipkin' include 'eventmesh-trace-plugin:eventmesh-trace-pinpoint' include 'eventmesh-trace-plugin:eventmesh-trace-jaeger' - include 'eventmesh-webhook' include 'eventmesh-webhook:eventmesh-webhook-api' include 'eventmesh-webhook:eventmesh-webhook-admin' include 'eventmesh-webhook:eventmesh-webhook-receive' -include 'eventmesh-security-plugin' -include 'eventmesh-security-plugin:eventmesh-security-api' -include 'eventmesh-security-plugin:eventmesh-security-auth-token' + +include 'eventmesh-retry' +include 'eventmesh-retry:eventmesh-retry-api' +include 'eventmesh-retry:eventmesh-retry-rocketmq' diff --git a/style/checkstyle-header1.txt b/style/checkstyle-header1.txt index 2944f98194..6a9c064171 100644 --- a/style/checkstyle-header1.txt +++ b/style/checkstyle-header1.txt @@ -14,3 +14,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + diff --git a/style/task/eventmesh-spotless-formatter.xml b/style/task/eventmesh-spotless-formatter.xml new file mode 100644 index 0000000000..e71522b7c6 --- /dev/null +++ b/style/task/eventmesh-spotless-formatter.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/dependency-check/known-dependencies.txt b/tools/dependency-check/known-dependencies.txt index 7179877a7f..408c5c6208 100644 --- a/tools/dependency-check/known-dependencies.txt +++ b/tools/dependency-check/known-dependencies.txt @@ -1,8 +1,17 @@ +ST4-4.3.4.jar +accessors-smart-2.4.7.jar +alibabacloud-gateway-spi-0.0.1.jar amqp-client-5.16.0.jar animal-sniffer-annotations-1.19.jar +annotations-2.20.29.jar annotations-4.1.1.4.jar -annotations-api-6.0.53.jar +antlr-runtime-3.5.3.jar +antlr4-4.13.0.jar +antlr4-runtime-4.13.0.jar aopalliance-1.0.jar +apache-client-2.20.29.jar +arns-2.20.29.jar +asm-9.1.jar asm-9.2.jar asm-analysis-9.2.jar asm-commons-9.2.jar @@ -12,20 +21,32 @@ assertj-core-2.6.0.jar async-http-client-2.12.0.jar async-http-client-netty-utils-2.12.0.jar audience-annotations-0.12.0.jar +auth-2.20.29.jar +aws-core-2.20.29.jar +aws-query-protocol-2.20.29.jar +aws-xml-protocol-2.20.29.jar bcpkix-jdk15on-1.69.jar +bcpkix-jdk15on-1.70.jar bcprov-ext-jdk15on-1.69.jar bcprov-ext-jdk15on-1.70.jar bcprov-jdk15on-1.69.jar +bcprov-jdk15on-1.70.jar bcutil-jdk15on-1.69.jar +bcutil-jdk15on-1.70.jar +bolt-1.1.6.jar bouncy-castle-bc-2.10.1-pkg.jar +bouncy-castle-bc-2.11.1-pkg.jar bson-3.12.11.jar byte-buddy-1.11.0.jar cache-api-1.1.1.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 -cloudevents-kafka-2.2.1.jar +classmate-1.5.1.jar +cloudevents-api-2.4.2.jar +cloudevents-core-2.4.2.jar +cloudevents-http-vertx-2.3.0.jar +cloudevents-json-jackson-2.4.2.jar +cloudevents-kafka-2.4.2.jar +cloudevents-protobuf-2.4.2.jar commons-beanutils-1.9.4.jar commons-cli-1.2.jar commons-codec-1.11.jar @@ -39,19 +60,25 @@ commons-logging-1.2.jar commons-text-1.9.jar commons-validator-1.7.jar consul-api-1.4.5.jar +credentials-java-0.2.4.jar +crt-core-2.20.29.jar curator-client-5.4.0.jar curator-framework-5.4.0.jar curator-recipes-5.4.0.jar +dingtalk-2.0.61.jar disruptor-3.4.2.jar dledger-0.3.1.2.jar +dom4j-2.0.3.jar +endpoint-util-0.0.7.jar +endpoints-spi-2.20.29.jar error_prone_annotations-2.9.0.jar +eventstream-1.0.1.jar failureaccess-1.0.1.jar fastjson-1.2.83.jar +gateway-dingtalk-1.0.2.jar google-auth-library-credentials-0.22.2.jar -grpc-api-1.42.2.jar grpc-api-1.43.2.jar grpc-auth-1.39.0.jar -grpc-context-1.42.2.jar grpc-context-1.43.2.jar grpc-core-1.43.2.jar grpc-grpclb-1.17.1.jar @@ -61,31 +88,44 @@ grpc-protobuf-1.42.2.jar grpc-protobuf-1.43.2.jar grpc-protobuf-lite-1.42.2.jar grpc-protobuf-lite-1.43.2.jar -grpc-stub-1.42.2.jar grpc-stub-1.43.2.jar gson-2.8.2.jar guava-31.0.1-jre.jar +guava-retrying-2.0.0.jar guice-4.2.2.jar -hamcrest-core-1.3.jar +hibernate-validator-6.2.0.Final.jar +http-client-spi-2.20.29.jar httpasyncclient-4.1.3.jar httpclient-4.5.13.jar httpcore-4.4.13.jar httpcore-nio-4.4.6.jar +httpmime-4.5.13.jar +icu4j-72.1.jar +ini4j-0.5.4.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 jackson-dataformat-yaml-2.13.0.jar +jackson-datatype-jsr310-2.13.0.jar +jakarta.annotation-api-1.3.5.jar +jakarta.validation-api-2.0.2.jar javassist-3.24.0-GA.jar javax.activation-1.2.0.jar javax.annotation-api-1.3.2.jar javax.inject-1.jar javax.ws.rs-api-2.1.jar +jaxb-api-2.3.0.jar +jaxb-core-2.3.0.jar +jaxb-impl-2.3.0.jar +jaxen-1.1.6.jar +jboss-logging-3.4.1.Final.jar jboss-marshalling-2.0.11.Final.jar jboss-marshalling-river-2.0.11.Final.jar jcip-annotations-1.0.jar jcommander-1.78.jar +jcommander-1.82.jar jetcd-common-0.3.0.jar jetcd-core-0.3.0.jar jetcd-resolver-0.3.0.jar @@ -95,44 +135,72 @@ jjwt-jackson-0.11.1.jar jna-4.2.2.jar jodd-bean-5.1.6.jar jodd-core-5.1.6.jar +json-path-2.7.0.jar +json-smart-2.4.7.jar +json-utils-2.20.29.jar jsr305-3.0.2.jar -junit-4.13.2.jar +jul-to-slf4j-1.7.33.jar kafka-clients-3.0.0.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 +log4j-api-2.22.1.jar +log4j-core-2.22.1.jar +log4j-slf4j2-impl-2.22.1.jar +log4j-slf4j-impl-2.22.1.jar +logback-classic-1.2.10.jar +logback-core-1.2.10.jar lz4-java-1.7.1.jar lz4-java-1.8.0.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 +metrics-spi-2.20.29.jar mongodb-driver-3.12.11.jar mongodb-driver-core-3.12.11.jar +mysql-binlog-connector-java-0.28.0.jar +mysql-connector-j-8.0.32.jar nacos-auth-plugin-2.2.1.jar nacos-client-2.2.1.jar nacos-encryption-plugin-2.2.1.jar netty-3.10.6.Final.jar netty-all-4.1.79.Final.jar +netty-buffer-4.1.100.Final.jar netty-buffer-4.1.79.Final.jar +netty-buffer-4.1.86.Final.jar +netty-codec-4.1.100.Final.jar netty-codec-4.1.79.Final.jar +netty-codec-4.1.86.Final.jar +netty-codec-dns-4.1.100.Final.jar netty-codec-dns-4.1.79.Final.jar netty-codec-haproxy-4.1.79.Final.jar +netty-codec-http-4.1.100.Final.jar netty-codec-http-4.1.79.Final.jar +netty-codec-http-4.1.86.Final.jar +netty-codec-http2-4.1.100.Final.jar netty-codec-http2-4.1.79.Final.jar +netty-codec-http2-4.1.86.Final.jar netty-codec-memcache-4.1.79.Final.jar netty-codec-mqtt-4.1.79.Final.jar netty-codec-redis-4.1.79.Final.jar netty-codec-smtp-4.1.79.Final.jar +netty-codec-socks-4.1.100.Final.jar netty-codec-socks-4.1.79.Final.jar netty-codec-stomp-4.1.79.Final.jar netty-codec-xml-4.1.79.Final.jar +netty-common-4.1.100.Final.jar netty-common-4.1.79.Final.jar +netty-common-4.1.86.Final.jar +netty-handler-4.1.100.Final.jar netty-handler-4.1.79.Final.jar +netty-handler-4.1.86.Final.jar +netty-handler-proxy-4.1.100.Final.jar netty-handler-proxy-4.1.79.Final.jar +netty-nio-client-2.20.29.jar netty-reactive-streams-2.0.4.jar +netty-resolver-4.1.100.Final.jar netty-resolver-4.1.79.Final.jar +netty-resolver-4.1.86.Final.jar +netty-resolver-dns-4.1.100.Final.jar netty-resolver-dns-4.1.79.Final.jar netty-resolver-dns-classes-macos-4.1.79.Final.jar netty-resolver-dns-native-macos-4.1.79.Final-osx-aarch_64.jar @@ -141,20 +209,27 @@ netty-tcnative-boringssl-static-2.0.48.Final.jar netty-tcnative-boringssl-static-2.0.51.Final.jar netty-tcnative-classes-2.0.48.Final.jar netty-tcnative-classes-2.0.51.Final.jar +netty-transport-4.1.100.Final.jar netty-transport-4.1.79.Final.jar +netty-transport-4.1.86.Final.jar netty-transport-classes-epoll-4.1.79.Final.jar +netty-transport-classes-epoll-4.1.86.Final.jar netty-transport-classes-kqueue-4.1.79.Final.jar netty-transport-native-epoll-4.1.79.Final-linux-aarch_64.jar netty-transport-native-epoll-4.1.79.Final-linux-x86_64.jar netty-transport-native-epoll-4.1.79.Final.jar netty-transport-native-kqueue-4.1.79.Final-osx-aarch_64.jar netty-transport-native-kqueue-4.1.79.Final-osx-x86_64.jar +netty-transport-native-unix-common-4.1.100.Final.jar netty-transport-native-unix-common-4.1.79.Final.jar +netty-transport-native-unix-common-4.1.86.Final.jar netty-transport-rxtx-4.1.79.Final.jar netty-transport-sctp-4.1.79.Final.jar netty-transport-udt-4.1.79.Final.jar +oapi-sdk-2.0.28.jar okhttp-3.14.9.jar okio-1.17.2.jar +openapiutil-0.2.1.jar openmessaging-api-2.2.1-pubsub.jar opentelemetry-api-1.3.0.jar opentelemetry-api-metrics-1.3.0-alpha.jar @@ -167,6 +242,8 @@ 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 +org.abego.treelayout.core-1.0.3.jar +org.jacoco.agent-0.8.4-runtime.jar perfmark-api-0.23.0.jar pinpoint-annotations-2.4.1.jar pinpoint-bootstrap-2.4.1.jar @@ -183,20 +260,28 @@ pravega-shared-authplugin-0.11.0.jar pravega-shared-controller-api-0.11.0.jar pravega-shared-protocol-0.11.0.jar pravega-shared-security-0.11.0.jar +profiles-2.20.29.jar proto-google-common-protos-2.0.1.jar -protobuf-java-3.18.2.jar protobuf-java-3.19.2.jar -protobuf-java-3.19.4.jar protobuf-java-3.21.5.jar +protobuf-java-3.21.9.jar +protobuf-java-util-3.15.0.jar protobuf-java-util-3.17.2.jar protobuf-java-util-3.21.5.jar protobuf-java-util-3.5.1.jar +protocol-core-2.20.29.jar +pull-parser-2.jar pulsar-client-2.10.1.jar +pulsar-client-2.11.1.jar pulsar-client-admin-api-2.10.1.jar +pulsar-client-admin-api-2.11.1.jar pulsar-client-api-2.10.1.jar +pulsar-client-api-2.11.1.jar reactive-streams-1.0.3.jar reactor-core-3.4.13.jar redisson-3.17.3.jar +regions-2.20.29.jar +relaxngDatatype-20020414.jar rocketmq-acl-4.9.5.jar rocketmq-broker-4.9.5.jar rocketmq-client-4.9.5.jar @@ -207,22 +292,52 @@ rocketmq-namesrv-4.9.5.jar rocketmq-remoting-4.9.5.jar rocketmq-srvutil-4.9.5.jar rocketmq-store-4.9.5.jar -rocketmq-test-4.9.5.jar rocketmq-tools-4.9.5.jar rxjava-3.0.12.jar +s3-2.20.29.jar +sdk-core-2.20.29.jar simpleclient-0.8.1.jar simpleclient_common-0.8.1.jar simpleclient_httpserver-0.8.1.jar -slf4j-api-1.7.30.jar +slack-api-client-1.1.6.jar +slack-api-model-1.1.6.jar +slack-app-backend-1.1.6.jar +slf4j-api-2.0.9.jar snakeyaml-1.30.jar snappy-java-1.1.8.1.jar -system-rules-1.16.1.jar -truth-0.30.jar +spring-aop-5.3.15.jar +spring-beans-5.3.20.jar +spring-boot-2.5.9.jar +spring-boot-autoconfigure-2.5.9.jar +spring-boot-starter-2.5.9.jar +spring-boot-starter-logging-2.5.9.jar +spring-boot-starter-validation-2.5.9.jar +spring-context-5.3.15.jar +spring-core-5.3.20.jar +spring-expression-5.3.15.jar +spring-jcl-5.3.20.jar +spring-messaging-5.3.20.jar +stax-api-1.0-2.jar +tea-1.2.7.jar +tea-openapi-0.2.8.jar +tea-util-0.2.21.jar +tea-xml-0.1.5.jar +third-party-jackson-core-2.20.29.jar +tomcat-embed-el-9.0.56.jar +utils-2.20.29.jar validation-api-1.1.0.Final.jar +vertx-auth-common-4.4.6.jar +vertx-bridge-common-4.4.6.jar +vertx-core-4.4.6.jar +vertx-web-4.4.6.jar +vertx-web-client-4.0.0.jar +vertx-web-common-4.4.6.jar +xpp3-1.1.4c.jar +xsdlib-2013.6.1.jar zipkin-2.23.2.jar zipkin-reporter-2.16.3.jar zipkin-sender-okhttp3-2.16.3.jar zookeeper-3.7.1.jar zookeeper-jute-3.7.1.jar zstd-jni-1.5.0-2.jar -zstd-jni-1.5.2-2.jar +zstd-jni-1.5.2-2.jar \ No newline at end of file diff --git a/tools/third-party-licenses/LICENSE b/tools/third-party-licenses/LICENSE index bf92fc7a95..de086f4883 100644 --- a/tools/third-party-licenses/LICENSE +++ b/tools/third-party-licenses/LICENSE @@ -215,6 +215,13 @@ 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. + alibabacloud-gateway-spi 0.0.1: http://www.aliyun.com Apache 2.0 + annotations 4.1.1.4: http://source.android.com/ Apache 2.0 + arns 2.20.29: https://aws.amazon.com/sdkforjava Apache 2.0 + auth 2.20.29: https://aws.amazon.com/sdkforjava Apache 2.0 + aws-core 2.20.29 https://aws.amazon.com/sdkforjava Apache 2.0 + aws-query-protocol 2.20.29 https://aws.amazon.com/sdkforjava Apache 2.0 + aws-xml-protocol 2.20.29 https://aws.amazon.com/sdkforjava Apache 2.0 assertj-core 2.6.0: https://github.com/assertj/assertj-core, Apache 2.0 async-http-client 2.12.0: https://github.com/AsyncHttpClient/async-http-client, Apache 2.0 byte-buddy 1.11.0: https://github.com/raphw/byte-buddy, Apache 2.0 @@ -222,6 +229,9 @@ The text of each license is also included at licenses/LICENSE-[project].txt. 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 + classmate 1.5.1: https://github.com/FasterXML/java-classmate, Apache 2.0 + crt-core 2.20.29: https://aws.amazon.com/sdkforjava, Apache 2.0 + eventstream 2.20.29: https://github.com/awslabs/aws-eventstream-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 @@ -237,11 +247,13 @@ The text of each license is also included at licenses/LICENSE-[project].txt. curator-recipes 4.0.1: https://github.com/apache/curator, 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 + dingtalk 2.0.61: https://github.com/aliyun/alibabacloud-sdk, 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 + fastjson 1.2.83: https://github.com/alibaba/fastjson, Apache 2.0 guava 31.0.1-jre: https://github.com/google/guava, Apache 2.0 + gateway-dingtalk 1.0.2: https://github.com/aliyun/alibabacloud-gateway, Apache 2.0 guice 4.2.2: https://github.com/google/guice, Apache 2.0 grpc-api 1.43.2: https://github.com/grpc/grpc-java, Apache-2.0 grpc-context 1.42.2: https://github.com/grpc/grpc-java, Apache 2.0 @@ -255,6 +267,8 @@ The text of each license is also included at licenses/LICENSE-[project].txt. gson 2.8.2: https://github.com/google/gson, Apache 2.0 httpasyncclient 4.1.3: https://github.com/apache/httpasyncclient, Apache 2.0 httpclient 4.5.13: https://github.com/apache/httpcomponents-client, Apache 2.0 + hibernate-validator 6.2.0.Final: https://github.com/hibernate/hibernate-validator, Apache 2.0 + httpmime 4.5.13: http://hc.apache.org/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 @@ -262,23 +276,27 @@ The text of each license is also included at licenses/LICENSE-[project].txt. jackson-databind 2.13.0: https://github.com/FasterXML/jackson-databind, Apache 2.0 javassist 3.24.0-GA/3.24.0-GA: https://github.com/jboss-javassist/javassist, Apache 2.0 javax.inject 1: https://github.com/javax-inject/javax-inject, Apache 2.0 + jboss-logging 3.4.1.Final:https://github.com/jboss-logging/jboss-logging, Apache 2.0 jboss-marshalling 2.0.11.Final:https://github.com/jboss-remoting/jboss-marshalling, Apache 2.0 jboss-marshalling-river 2.0.11.Final: https://github.com/jboss-remoting/jboss-marshalling, Apache 2.0 jcip-annotations 1.0: https://github.com/stephenc/jcip-annotations, Apache 2.0 jcommander 1.72: https://github.com/cbeust/jcommander, Apache 2.0 jetcd-common 0.3.0: https://github.com/etcd-io/jetcd, Apache 2.0 + json-utils 2.20.29: https://aws.amazon.com/sdkforjava, Apache 2.0 jetcd-core 0.3.0: https://github.com/etcd-io/jetcd, Apache 2.0 jetcd-resolver 0.3.0: https://github.com/etcd-io/jetcd, Apache 2.0 jna 4.2.2: https://github.com/java-native-access/jna, Apache 2.0 kafka-clients 3.0.0: https://github.com/apache/kafka, 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 + log4j-api 2.22.1: https://github.com/apache/logging-log4j2, Apache 2.0 + log4j-core 2.22.1: https://github.com/apache/logging-log4j2, Apache 2.0 + log4j-slf4j2-impl 2.22.1: https://github.com/apache/logging-log4j2, Apache 2.0 + log4j-slf4j-impl 2.22.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 nacos-auth-plugin 2.1.0: https://github.com/alibaba/nacos, Apache 2.0 + mysql-binlog-connector-java 0.28.0: https://github.com/osheroff/mysql-binlog-connector-java, Apache 2.0 nacos-client 2.0.4: https://github.com/alibaba/nacos, Apache 2.0 nacos-encryption-plugin 2.1.0: https://github.com/alibaba/nacos, Apache 2.0 netty-all 4.1.73.Final: https://github.com/netty/netty/tree/netty-4.1.73.Final, Apache 2.0 @@ -331,6 +349,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt. 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 + oapi-sdk 2.0.28: ttps://github.com/larksuite/oapi-sdk-java, Apache 2.0 perfmark-api 0.23.0: https://github.com/perfmark/perfmark, Apache 2.0 pinpoint-annotations 2.4.1: https://github.com/pinpoint-apm/pinpoint, Apache 2.0 pinpoint-bootstrap 2.4.1: https://github.com/pinpoint-apm/pinpoint, Apache 2.0 @@ -341,6 +360,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt. pinpoint-grpc 2.4.1: https://github.com/pinpoint-apm/pinpoint, Apache 2.0 pinpoint-profiler 2.4.1: https://github.com/pinpoint-apm/pinpoint, Apache 2.0 pinpoint-rpc 2.4.1: https://github.com/pinpoint-apm/pinpoint, Apache 2.0 + profiles 2.20.29: https://aws.amazon.com/sdkforjava, Apache 2.0 pravega-client 0.11.0: https://github.com/pravega/pravega, Apache 2.0 pravega-common 0.11.0: https://github.com/pravega/pravega, Apache 2.0 pravega-shared-authplugin 0.11.0: https://github.com/pravega/pravega, Apache 2.0 @@ -350,6 +370,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt. proto-google-common-protos 1.0.0: https://github.com/googleapis/common-protos-java, Apache 2.0 pulsar-client 2.10.1: https://github.com/apache/pulsar, Apache 2.0 pulsar-client-admin-api 2.10.1: https://github.com/apache/pulsar, Apache 2.0 + protocol-core 2.20.29: https://aws.amazon.com/sdkforjava, Apache 2.0 pulsar-client-api 2.10.1: https://github.com/apache/pulsar, Apache 2.0 reactor-core 3.4.13: https://github.com/reactor/reactor-core, Apache 2.0 rocketmq-acl 4.9.3: https://github.com/apache/rocketmq, Apache 2.0 @@ -367,32 +388,27 @@ The text of each license is also included at licenses/LICENSE-[project].txt. 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.30: https://bitbucket.org/asomov/snakeyaml, Apache 2.0 + snakeyaml 2.0: https://bitbucket.org/asomov/snakeyaml, Apache 2.0 + s3 2.20.29: https://aws.amazon.com/sdkforjava, Apache 2.0 + sdk-core 2.20.29: https://aws.amazon.com/sdkforjava, Apache 2.0 + spring-aop 5.3.15: https://github.com/spring-projects/spring-framework, Apache 2.0 + spring-beans 5.3.20: https://github.com/spring-projects/spring-framework, Apache 2.0 + spring-context 5.3.15: https://github.com/spring-projects/spring-framework, Apache 2.0 + spring-core 5.3.20: https://github.com/spring-projects/spring-framework, Apache 2.0 + spring-expression 5.3.15: https://github.com/spring-projects/spring-framework, Apache 2.0 + spring-jcl 5.3.20: https://github.com/spring-projects/spring-framework, Apache 2.0 + spring-messaging 5.3.20: https://github.com/spring-projects/spring-framework, Apache 2.0 + spring-boot 2.5.9: https://github.com/spring-projects/spring-boot, Apache 2.0 + spring-boot-autoconfigure 2.5.9: https://github.com/spring-projects/spring-boot, Apache 2.0 + spring-boot-starter 2.5.9: https://github.com/spring-projects/spring-boot, Apache 2.0 + spring-boot-starter-logging 2.5.9: https://github.com/spring-projects/spring-boot, Apache 2.0 + spring-boot-starter-validation 2.5.9: https://github.com/spring-projects/spring-boot, Apache 2.0 truth 0.30: https://github.com/google/truth, Apache 2.0 validation-api 1.1.0.Final: https://github.com/jakartaee/validation, 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 zookeeper 3.4.6: https://github.com/apache/zookeeper, 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 @@ -434,6 +450,8 @@ The following components are provided under the EPL License. See project link fo The text of each license is also included at licenses/LICENSE-[project].txt. junit 4.13.2: https://github.com/junit-team/junit5, EPL + jakarta.annotation-api 1.3.5: https://projects.eclipse.org/projects/ee4j.ca, EPL + jakarta.validation-api 2.0.2: https://beanvalidation.org, EPL ======================================================================== MIT licenses @@ -449,28 +467,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt. bcutil-jdk15on 1.69: https://github.com/bcgit/bc-java, MIT checker-qual 3.12.0: https://github.com/typetools/checker-framework, MIT reactive-streams 1.0.3: https://github.com/reactive-streams/reactive-streams-jvm, 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 + slf4j-api 2.0.9: https://github.com/qos-ch/slf4j, MIT ======================================================================== BSD-3-Clause licenses @@ -480,32 +477,10 @@ The following components are provided under the BSD-3-Clause License. See projec The text of each license is also included at licenses/license-[project].txt. jline 0.9.94: https://github.com/jline, BSD-3-Clause - 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 + ST4 4.3.4: https://github.com/antlr/antlr4, BSD-3-Clause + antlr4-runtime 4.13.0: https://github.com/antlr/antlr4, BSD-3-Clause + antlr4 4.13.0: https://github.com/antlr/antlr4, BSD-3-Clause + dom4j 2.0.3: https://github.com/dom4j/dom4j, BSD-3-Clause ======================================================================== BSD-2-Clause licenses @@ -516,23 +491,21 @@ The text of each license is also included at licenses/license-[project].txt. jodd-bean 5.1.6: https://github.com/oblac/jodd-util, BSD-2-Clause jodd-core 5.1.6: https://github.com/oblac/jodd, BSD-2-Clause - 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 +MPL & GPL & Apache licenses ======================================================================== -The following components are provided under the MIT and Apache License. See project link for details. +The following components are provided under the MPL & GPL & 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 + amqp-client 5.16.0: https://github.com/rabbitmq/rabbitmq-java-client MPL & GPL & Apache License + ======================================================================== -MPL & GPL & Apache licenses +CDDL & GPL2 ======================================================================== - -The following components are provided under the MPL & GPL & Apache License. See project link for details. +The following components are provided under the CDDL & GPL2. See project link for details. The text of each license is also included at licenses/license-[project].txt. - amqp-client 5.16.0: https://github.com/rabbitmq/rabbitmq-java-client MPL & GPL & Apache License + jaxb-api 2.3.0: http://www.oracle.com/ CDDL & GPL2 \ No newline at end of file diff --git a/tools/third-party-licenses/NOTICE b/tools/third-party-licenses/NOTICE index a079639bf7..c245a33856 100644 --- a/tools/third-party-licenses/NOTICE +++ b/tools/third-party-licenses/NOTICE @@ -946,3 +946,138 @@ Ocelli project by Netflix Inc. (https://github.com/Netflix/ocelli/). =============================================================================== +AWS SDK NOTICE + +=============================================================================== +AWS SDK for Java 2.0 +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + +This product includes software developed by +Amazon Technologies, Inc (http://www.amazon.com/). + +********************** +THIRD PARTY COMPONENTS +********************** +This software includes third party software subject to the following copyrights: +- XML parsing and utility functions from JetS3t - Copyright 2006-2009 James Murty. +- PKCS#1 PEM encoded private key parsing and utility functions from oauth.googlecode.com - Copyright 1998-2010 AOL Inc. +- Apache Commons Lang - https://github.com/apache/commons-lang +- Netty Reactive Streams - https://github.com/playframework/netty-reactive-streams +- Jackson-core - https://github.com/FasterXML/jackson-core +- Jackson-dataformat-cbor - https://github.com/FasterXML/jackson-dataformats-binary + +The licenses for these third party components are included in LICENSE.txt + +- For Apache Commons Lang see also this required NOTICE: + Apache Commons Lang + Copyright 2001-2020 The Apache Software Foundation + + This product includes software developed at + The Apache Software Foundation (https://www.apache.org/). + +=============================================================================== + +Apache HttpClient Mime NOTICE + +=============================================================================== +Apache HttpClient Mime +Copyright 1999-2020 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +Jakarta Annotations NOTICE + +=============================================================================== +This content is produced and maintained by the Jakarta Annotations project. + + * Project home: https://projects.eclipse.org/projects/ee4j.ca + +## Trademarks + +Jakarta Annotations is a trademark of the Eclipse Foundation. + +## Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Eclipse Public License v. 2.0 which is available at +http://www.eclipse.org/legal/epl-2.0. This Source Code may also be made +available under the following Secondary Licenses when the conditions for such +availability set forth in the Eclipse Public License v. 2.0 are satisfied: GNU +General Public License, version 2 with the GNU Classpath Exception which is +available at https://www.gnu.org/software/classpath/license.html. + +SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + +## Source Code + +The project maintains the following source code repositories: + + * https://github.com/eclipse-ee4j/common-annotations-api + +## Third-party Content + +## Cryptography + +Content may contain encryption software. The country in which you are currently +may have restrictions on the import, possession, and use, and/or re-export to +another country, of encryption software. BEFORE using any encryption software, +please check the country's laws, regulations and policies concerning the import, +possession, or use, and re-export of encryption software, to see if this is +permitted. + +=============================================================================== + +Apache Log4j to SLF4J Adapter NOTICE + +=============================================================================== +Apache Log4j to SLF4J Adapter +Copyright 1999-1969 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== + +Spring Framework NOTICE + +=============================================================================== +Spring Framework 5.3.15 +Copyright (c) 2002-2022 Pivotal, Inc. + +This product is licensed to you under the Apache License, Version 2.0 +(the "License"). You may not use this product except in compliance with +the License. + +This product may include a number of subcomponents with separate +copyright notices and license terms. Your use of the source code for +these subcomponents is subject to the terms and conditions of the +subcomponent's license, as noted in the license.txt file. + +=============================================================================== + +Spring Boot NOTICE + +=============================================================================== + +Spring Boot 2.5.9 +Copyright (c) 2012-2022 Pivotal, Inc. + +This product is licensed to you under the Apache License, Version 2.0 +(the "License"). You may not use this product except in compliance with +the License. + +=============================================================================== + +Apache Tomcat NOTICE + +=============================================================================== +Apache Tomcat +Copyright 1999-2021 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +=============================================================================== \ 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 deleted file mode 100644 index 01b5743200..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-BurntSushi-toml.txt +++ /dev/null @@ -1,21 +0,0 @@ -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 deleted file mode 100644 index e64dffa0a9..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-OneOfOne-xxhash.txt +++ /dev/null @@ -1,187 +0,0 @@ - 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-aliyun-alibaba-cloud-sdk-go.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-aliyun-alibaba-cloud-sdk-go.txt deleted file mode 100644 index de095ef1a9..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-aliyun-alibaba-cloud-sdk-go.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 (c) 2009-present, Alibaba Cloud All rights reserved. - - 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-antihax-optional.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-antihax-optional.txt deleted file mode 100644 index 6a2c64ab1f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-antihax-optional.txt +++ /dev/null @@ -1,8 +0,0 @@ -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-apache-rocketmq-client-go-v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-apache-rocketmq-client-go-v2.txt deleted file mode 100644 index 3d33284651..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-apache-rocketmq-client-go-v2.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-asyncapi-converter-go.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-asyncapi-converter-go.txt deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-asyncapi-converter-go.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-asyncapi-parser-go.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-asyncapi-parser-go.txt deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-asyncapi-parser-go.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-asyncapi-spec-json-schemas-v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-asyncapi-spec-json-schemas-v2.txt deleted file mode 100644 index 9453962d52..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-asyncapi-spec-json-schemas-v2.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 The Linux 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/go/LICENSE-github.com-avast-retry-go-v4.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-avast-retry-go-v4.txt deleted file mode 100644 index 89a39a513f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-avast-retry-go-v4.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Avast - -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-beorn7-perks.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-beorn7-perks.txt deleted file mode 100644 index e52e03f1cc..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-beorn7-perks.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (C) 2013 Blake Mizerany - -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-buger-jsonparser.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-buger-jsonparser.txt deleted file mode 100644 index 7dad6acda0..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-buger-jsonparser.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Leonid Bugaev - -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 deleted file mode 100644 index bfcfcd3013..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-client9-misspell.txt +++ /dev/null @@ -1,21 +0,0 @@ -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-cncf-udpa-go.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-cncf-udpa-go.txt deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-cncf-udpa-go.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-cncf-xds-go.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 deleted file mode 100644 index 6b761042bf..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-creack-pty.txt +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 7304bdf8cb..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-davecgh-go-spew.txt +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index efd4827e21..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-deckarep-golang-set.txt +++ /dev/null @@ -1,22 +0,0 @@ -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 deleted file mode 100644 index 9c8f3ea087..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-envoyproxy-go-control-plane.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-fsnotify-fsnotify.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-fsnotify-fsnotify.txt deleted file mode 100644 index c656a4322e..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-fsnotify-fsnotify.txt +++ /dev/null @@ -1,25 +0,0 @@ -Copyright © 2012 The Go Authors. All rights reserved. -Copyright © fsnotify 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-ghodss-yaml.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-ghodss-yaml.txt deleted file mode 100644 index e137618b0f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-ghodss-yaml.txt +++ /dev/null @@ -1,50 +0,0 @@ -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-gin-contrib-pprof.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-gin-contrib-pprof.txt deleted file mode 100644 index 952e7d0ab7..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-gin-contrib-pprof.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Gin-Gonic - -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-gin-contrib-sse.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-gin-contrib-sse.txt deleted file mode 100644 index 234880dcb8..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-gin-contrib-sse.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Manuel Martínez-Almeida - -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-gin-gonic-gin.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-gin-gonic-gin.txt deleted file mode 100644 index 234880dcb8..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-gin-gonic-gin.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Manuel Martínez-Almeida - -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-go-errors-errors.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-errors-errors.txt deleted file mode 100644 index 61b40eeef9..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-errors-errors.txt +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (c) 2015 Conrad Irwin - -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-go-openapi-jsonreference.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-openapi-jsonreference.txt deleted file mode 100644 index 7a4a3ea242..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-openapi-jsonreference.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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-go-openapi-spec.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-openapi-spec.txt deleted file mode 100644 index 7a4a3ea242..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-openapi-spec.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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-go-openapi-swag.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-openapi-swag.txt deleted file mode 100644 index 7a4a3ea242..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-openapi-swag.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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-go-playground-locales.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-playground-locales.txt deleted file mode 100644 index 75854ac4f0..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-playground-locales.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Go Playground - -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-go-playground-universal-translator.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-playground-universal-translator.txt deleted file mode 100644 index 75854ac4f0..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-playground-universal-translator.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Go Playground - -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-go-playground-validator-v10.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-playground-validator-v10.txt deleted file mode 100644 index ab4304b3cd..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-playground-validator-v10.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Dean Karn - -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-go-sql-driver-mysql.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-sql-driver-mysql.txt deleted file mode 100644 index fa0086a952..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-go-sql-driver-mysql.txt +++ /dev/null @@ -1,373 +0,0 @@ -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/go/LICENSE-github.com-goccy-go-json.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-goccy-go-json.txt deleted file mode 100644 index 90ef3730cb..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-goccy-go-json.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Masaaki Goshima - -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-gogf-gf.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-gogf-gf.txt deleted file mode 100644 index 0b6bc3a5f4..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-gogf-gf.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 john@goframe.org https://goframe.org - -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-golang-glog.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-glog.txt deleted file mode 100644 index 8405e89a0b..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-glog.txt +++ /dev/null @@ -1,191 +0,0 @@ -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 deleted file mode 100644 index 7a4a3ea242..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-mock.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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 deleted file mode 100644 index 8e63345bc2..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-golang-protobuf.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index d9b732cfd3..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-go-cmp.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index 7a4a3ea242..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-google-gofuzz.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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-grpc-ecosystem-grpc-gateway.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-grpc-ecosystem-grpc-gateway.txt deleted file mode 100644 index 6e59e318a1..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-grpc-ecosystem-grpc-gateway.txt +++ /dev/null @@ -1,27 +0,0 @@ -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-hashicorp-errwrap.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-hashicorp-errwrap.txt deleted file mode 100644 index 82b4de97c7..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-hashicorp-errwrap.txt +++ /dev/null @@ -1,353 +0,0 @@ -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. diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-hashicorp-go-multierror.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-hashicorp-go-multierror.txt deleted file mode 100644 index cdff15cd53..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-hashicorp-go-multierror.txt +++ /dev/null @@ -1,353 +0,0 @@ -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/go/LICENSE-github.com-inconshreveable-mousetrap.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-inconshreveable-mousetrap.txt deleted file mode 100644 index 01109bbff3..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-inconshreveable-mousetrap.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 2022 Alan Shreve (@inconshreveable) - - 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-itchyny-gojq.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-itchyny-gojq.txt deleted file mode 100644 index 13fd2944ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-itchyny-gojq.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2019-2022 itchyny - -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-jinzhu-inflection.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-jinzhu-inflection.txt deleted file mode 100644 index f39e7202f4..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-jinzhu-inflection.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 - Jinzhu - -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-jinzhu-now.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-jinzhu-now.txt deleted file mode 100644 index 9c8526e909..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-jinzhu-now.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013-NOW Jinzhu - -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-jmespath-go-jmespath.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-jmespath-go-jmespath.txt deleted file mode 100644 index 7a4a3ea242..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-jmespath-go-jmespath.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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-kr-pty.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-kr-pty.txt deleted file mode 100644 index 35934dbf5e..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-kr-pty.txt +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 2e9e336a3f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-kr-text.txt +++ /dev/null @@ -1,19 +0,0 @@ -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-leodido-go-urn.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-leodido-go-urn.txt deleted file mode 100644 index ed0af7b31b..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-leodido-go-urn.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Leonardo Di Donato - -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-lestrrat-go-strftime.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-lestrrat-go-strftime.txt deleted file mode 100644 index 4e95cc3a2d..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-lestrrat-go-strftime.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 lestrrat - -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-liyue201-gostl.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-liyue201-gostl.txt deleted file mode 100644 index ee25ffddd2..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-liyue201-gostl.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 stirlingx - -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-mattn-go-isatty.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-mattn-go-isatty.txt deleted file mode 100644 index d609ea5ebc..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-mattn-go-isatty.txt +++ /dev/null @@ -1,9 +0,0 @@ -Copyright (c) Yasuhiro MATSUMOTO - -MIT License (Expat) - -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-matttproud-golang_protobuf_extensions.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-matttproud-golang_protobuf_extensions.txt deleted file mode 100644 index 9c8f3ea087..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-matttproud-golang_protobuf_extensions.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-mitchellh-mapstructure.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-mitchellh-mapstructure.txt deleted file mode 100644 index 09fffd383e..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-mitchellh-mapstructure.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 Mitchell Hashimoto - -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 deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-modern-go-concurrent.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-modern-go-reflect2.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-nacos-group-nacos-sdk-go-v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-nacos-group-nacos-sdk-go-v2.txt deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-nacos-group-nacos-sdk-go-v2.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 deleted file mode 100644 index 2e9e336a3f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-niemeyer-pretty.txt +++ /dev/null @@ -1,19 +0,0 @@ -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-pelletier-go-toml-v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-pelletier-go-toml-v2.txt deleted file mode 100644 index 5b769ab525..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-pelletier-go-toml-v2.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 - 2022 Thomas Pelletier, Eric Anderton - -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 deleted file mode 100644 index 1906e68097..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-pkg-errors.txt +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 485be13c67..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-pmezard-go-difflib.txt +++ /dev/null @@ -1,27 +0,0 @@ -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_golang.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-client_golang.txt deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-client_golang.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-prometheus-client_model.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-client_model.txt deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-client_model.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-prometheus-common.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-common.txt deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-common.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-prometheus-procfs.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-procfs.txt deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-prometheus-procfs.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-reactivex-rxgo-v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-reactivex-rxgo-v2.txt deleted file mode 100644 index 1c00bfab3f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-reactivex-rxgo-v2.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Joe Chasinga - -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-rogpeppe-fastuuid.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-rogpeppe-fastuuid.txt deleted file mode 100644 index f84b5232e7..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-rogpeppe-fastuuid.txt +++ /dev/null @@ -1,26 +0,0 @@ -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-serverlessworkflow-sdk-go-v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-serverlessworkflow-sdk-go-v2.txt deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-serverlessworkflow-sdk-go-v2.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-spaolacci-murmur3.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-spaolacci-murmur3.txt deleted file mode 100644 index 8eeb61967a..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-spaolacci-murmur3.txt +++ /dev/null @@ -1,24 +0,0 @@ -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-spf13-pflag.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-spf13-pflag.txt deleted file mode 100644 index e33bc4c751..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-spf13-pflag.txt +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2012 Alex Ogier. All rights reserved. -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-stretchr-objx.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-stretchr-objx.txt deleted file mode 100644 index 5b30a3704f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-stretchr-objx.txt +++ /dev/null @@ -1,22 +0,0 @@ -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-swaggo-files.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-swaggo-files.txt deleted file mode 100644 index 64ef3d0d74..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-swaggo-files.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Swaggo - -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-swaggo-gin-swagger.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-swaggo-gin-swagger.txt deleted file mode 100644 index 8c16ff84f0..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-swaggo-gin-swagger.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Swaggo - -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-swaggo-swag.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-swaggo-swag.txt deleted file mode 100644 index 99436a322f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-swaggo-swag.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Eason Lin - -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-ugorji-go.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-ugorji-go.txt deleted file mode 100644 index 37c671078f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-ugorji-go.txt +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2012-2020 Ugorji Nwoke. -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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/go/LICENSE-github.com-unrolled-secure.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-unrolled-secure.txt deleted file mode 100644 index c1b34f99ef..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-unrolled-secure.txt +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Cory Jacobsen - -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-urfave-cli-v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-urfave-cli-v2.txt deleted file mode 100644 index 55c42a9e53..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-urfave-cli-v2.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 urfave/cli maintainers - -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 deleted file mode 100644 index 8d25e9a147..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-valyala-bytebufferpool.txt +++ /dev/null @@ -1,21 +0,0 @@ -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-github.com-xeipuuv-gojsonpointer.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-xeipuuv-gojsonpointer.txt deleted file mode 100644 index c5cec753c0..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-xeipuuv-gojsonpointer.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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 2015 xeipuuv - - 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-xeipuuv-gojsonreference.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-xeipuuv-gojsonreference.txt deleted file mode 100644 index c5cec753c0..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-xeipuuv-gojsonreference.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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 2015 xeipuuv - - 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-xeipuuv-gojsonschema.txt b/tools/third-party-licenses/licenses/go/LICENSE-github.com-xeipuuv-gojsonschema.txt deleted file mode 100644 index c5cec753c0..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-github.com-xeipuuv-gojsonschema.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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 2015 xeipuuv - - 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.opentelemetry.io-proto-otlp.txt b/tools/third-party-licenses/licenses/go/LICENSE-go.opentelemetry.io-proto-otlp.txt deleted file mode 100644 index 30f8920b6a..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-go.opentelemetry.io-proto-otlp.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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-dig.txt b/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-dig.txt deleted file mode 100644 index 300ce9b9e7..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-dig.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2017-2018 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-fx.txt b/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-fx.txt deleted file mode 100644 index 300ce9b9e7..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-fx.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2017-2018 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 deleted file mode 100644 index 5bfe7bb6d9..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-go.uber.org-multierr.txt +++ /dev/null @@ -1,19 +0,0 @@ -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-golang.org-x-crypto.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-crypto.txt deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-crypto.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-exp.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index 65d761bc9f..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-lint.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-net.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-oauth2.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-sync.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-sys.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-text.txt +++ /dev/null @@ -1,27 +0,0 @@ -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-time.txt b/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-time.txt deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-time.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-tools.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index e4a47e17f1..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-golang.org-x-xerrors.txt +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index f49a4e16e6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-appengine.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 deleted file mode 100644 index 7a4a3ea242..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-google.golang.org-genproto.txt +++ /dev/null @@ -1,202 +0,0 @@ - - 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 deleted file mode 100644 index eea77e192a..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-check.v1.txt +++ /dev/null @@ -1,25 +0,0 @@ -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-ini.v1.txt b/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-ini.v1.txt deleted file mode 100644 index 3f78a807f6..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-ini.v1.txt +++ /dev/null @@ -1,191 +0,0 @@ -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 2014 Unknwon - - 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-natefinch-lumberjack.v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-natefinch-lumberjack.v2.txt deleted file mode 100644 index 8d6bb4a46c..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-natefinch-lumberjack.v2.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Nate Finch - -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-gopkg.in-yaml.v2.txt b/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-yaml.v2.txt deleted file mode 100644 index 9c8f3ea087..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-yaml.v2.txt +++ /dev/null @@ -1,201 +0,0 @@ - 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 deleted file mode 100644 index ce5fc85d7b..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-gopkg.in-yaml.v3.txt +++ /dev/null @@ -1,50 +0,0 @@ - -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-gorm.io-driver-mysql.txt b/tools/third-party-licenses/licenses/go/LICENSE-gorm.io-driver-mysql.txt deleted file mode 100644 index 9c8526e909..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-gorm.io-driver-mysql.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013-NOW Jinzhu - -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-gorm.io-gorm.txt b/tools/third-party-licenses/licenses/go/LICENSE-gorm.io-gorm.txt deleted file mode 100644 index 9c8526e909..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-gorm.io-gorm.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013-NOW Jinzhu - -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-honnef.co-go-tools.txt b/tools/third-party-licenses/licenses/go/LICENSE-honnef.co-go-tools.txt deleted file mode 100644 index 0dd5c21067..0000000000 --- a/tools/third-party-licenses/licenses/go/LICENSE-honnef.co-go-tools.txt +++ /dev/null @@ -1,20 +0,0 @@ -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-ST4.txt b/tools/third-party-licenses/licenses/java/LICENSE-ST4.txt new file mode 100644 index 0000000000..83290392f8 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-ST4.txt @@ -0,0 +1,28 @@ +Copyright (c) 2012-2022 The ANTLR Project. 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. + +3. Neither name of copyright holders 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 REGENTS 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-cloud.google.com-go.txt b/tools/third-party-licenses/licenses/java/LICENSE-alibabacloud-gateway-spi.txt similarity index 100% rename from tools/third-party-licenses/licenses/go/LICENSE-cloud.google.com-go.txt rename to tools/third-party-licenses/licenses/java/LICENSE-alibabacloud-gateway-spi.txt diff --git a/tools/third-party-licenses/licenses/java/LICENSE-antlr4-runtime.txt b/tools/third-party-licenses/licenses/java/LICENSE-antlr4-runtime.txt new file mode 100644 index 0000000000..83290392f8 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-antlr4-runtime.txt @@ -0,0 +1,28 @@ +Copyright (c) 2012-2022 The ANTLR Project. 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. + +3. Neither name of copyright holders 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 REGENTS 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-apache-client.txt b/tools/third-party-licenses/licenses/java/LICENSE-apache-client.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-apache-client.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-arns.txt b/tools/third-party-licenses/licenses/java/LICENSE-arns.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-arns.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-auth.txt b/tools/third-party-licenses/licenses/java/LICENSE-auth.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-auth.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-aws-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-aws-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-aws-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-aws-query-protocol.txt b/tools/third-party-licenses/licenses/java/LICENSE-aws-query-protocol.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-aws-query-protocol.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-aws-xml-protocol.txt b/tools/third-party-licenses/licenses/java/LICENSE-aws-xml-protocol.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-aws-xml-protocol.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-bolt.txt b/tools/third-party-licenses/licenses/java/LICENSE-bolt.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-bolt.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-classmate.txt b/tools/third-party-licenses/licenses/java/LICENSE-classmate.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-classmate.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-credentials-java.txt b/tools/third-party-licenses/licenses/java/LICENSE-credentials-java.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-credentials-java.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-crt-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-crt-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-crt-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-dingtalk.txt b/tools/third-party-licenses/licenses/java/LICENSE-dingtalk.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-dingtalk.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-dom4j.txt b/tools/third-party-licenses/licenses/java/LICENSE-dom4j.txt new file mode 100644 index 0000000000..d076d0c54b --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-dom4j.txt @@ -0,0 +1,39 @@ +Copyright 2001-2023 © MetaStuff, Ltd. and DOM4J contributors. All Rights Reserved. + +Redistribution and use of this software and associated documentation +("Software"), with or without modification, are permitted provided +that the following conditions are met: + +1. Redistributions of source code must retain copyright + statements and notices. Redistributions must also contain a + copy of this document. + +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. The name "DOM4J" must not be used to endorse or promote + products derived from this Software without prior written + permission of MetaStuff, Ltd. For written permission, + please contact dom4j-info@metastuff.com. + +4. Products derived from this Software may not be called "DOM4J" + nor may "DOM4J" appear in their names without prior written + permission of MetaStuff, Ltd. DOM4J is a registered + trademark of MetaStuff, Ltd. + +5. Due credit should be given to the DOM4J Project - https://dom4j.github.io/ + +THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESSED 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 +METASTUFF, LTD. OR ITS 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-endpoint-util.txt b/tools/third-party-licenses/licenses/java/LICENSE-endpoint-util.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-endpoint-util.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-endpoints-spi.txt b/tools/third-party-licenses/licenses/java/LICENSE-endpoints-spi.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-endpoints-spi.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-eventstream.txt b/tools/third-party-licenses/licenses/java/LICENSE-eventstream.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-eventstream.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-gateway-dingtalk.txt b/tools/third-party-licenses/licenses/java/LICENSE-gateway-dingtalk.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-gateway-dingtalk.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-hibernate-validator.txt b/tools/third-party-licenses/licenses/java/LICENSE-hibernate-validator.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-hibernate-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. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-http-client-spi.txt b/tools/third-party-licenses/licenses/java/LICENSE-http-client-spi.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-http-client-spi.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-httpmime.txt b/tools/third-party-licenses/licenses/java/LICENSE-httpmime.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-httpmime.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-icu4j.txt b/tools/third-party-licenses/licenses/java/LICENSE-icu4j.txt new file mode 100644 index 0000000000..5c8b343051 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-icu4j.txt @@ -0,0 +1,512 @@ +UNICODE LICENSE V3 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 2016-2023 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE 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 OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 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 THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. + +---------------------------------------------------------------------- + +Third-Party Software Licenses + +This section contains third-party software notices and/or additional +terms for licensed third-party software components included within ICU +libraries. + +---------------------------------------------------------------------- + +ICU License - ICU 1.8.1 to ICU 57.1 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1995-2016 International Business Machines Corporation and others +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, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +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 +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY +SPECIAL 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. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +All trademarks and registered trademarks mentioned herein are the +property of their respective owners. + +---------------------------------------------------------------------- + +Chinese/Japanese Word Break Dictionary Data (cjdict.txt) + + # The Google Chrome software developed by Google is licensed under + # the BSD license. Other software included in this distribution is + # provided under other licenses, as set forth below. + # + # The BSD License + # http://opensource.org/licenses/bsd-license.php + # Copyright (C) 2006-2008, Google Inc. + # + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are met: + # + # Redistributions of source code must retain the above copyright notice, + # this list of conditions and the following disclaimer. + # Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following + # disclaimer in the documentation and/or other materials provided with + # the distribution. + # Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # + # + # The word list in cjdict.txt are generated by combining three word lists + # listed below with further processing for compound word breaking. The + # frequency is generated with an iterative training against Google web + # corpora. + # + # * Libtabe (Chinese) + # - https://sourceforge.net/project/?group_id=1519 + # - Its license terms and conditions are shown below. + # + # * IPADIC (Japanese) + # - http://chasen.aist-nara.ac.jp/chasen/distribution.html + # - Its license terms and conditions are shown below. + # + # ---------COPYING.libtabe ---- BEGIN-------------------- + # + # /* + # * Copyright (c) 1999 TaBE Project. + # * Copyright (c) 1999 Pai-Hsiang Hsiao. + # * 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 TaBE 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 + # * REGENTS 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. + # */ + # + # /* + # * Copyright (c) 1999 Computer Systems and Communication Lab, + # * Institute of Information Science, Academia + # * Sinica. 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 Computer Systems and Communication Lab + # * 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 + # * REGENTS 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. + # */ + # + # Copyright 1996 Chih-Hao Tsai @ Beckman Institute, + # University of Illinois + # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4 + # + # ---------------COPYING.libtabe-----END-------------------------------- + # + # + # ---------------COPYING.ipadic-----BEGIN------------------------------- + # + # Copyright 2000, 2001, 2002, 2003 Nara Institute of Science + # and Technology. All Rights Reserved. + # + # Use, reproduction, and distribution of this software is permitted. + # Any copy of this software, whether in its original form or modified, + # must include both the above copyright notice and the following + # paragraphs. + # + # Nara Institute of Science and Technology (NAIST), + # the copyright holders, disclaims all warranties with regard to this + # software, including all implied warranties of merchantability and + # fitness, in no event shall NAIST be liable for + # any special, 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 tortuous action, arising out + # of or in connection with the use or performance of this software. + # + # A large portion of the dictionary entries + # originate from ICOT Free Software. The following conditions for ICOT + # Free Software applies to the current dictionary as well. + # + # Each User may also freely distribute the Program, whether in its + # original form or modified, to any third party or parties, PROVIDED + # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear + # on, or be attached to, the Program, which is distributed substantially + # in the same form as set out herein and that such intended + # distribution, if actually made, will neither violate or otherwise + # contravene any of the laws and regulations of the countries having + # jurisdiction over the User or the intended distribution itself. + # + # NO WARRANTY + # + # The program was produced on an experimental basis in the course of the + # research and development conducted during the project and is provided + # to users as so produced on an experimental basis. Accordingly, the + # program is provided without any warranty whatsoever, whether express, + # implied, statutory or otherwise. The term "warranty" used herein + # includes, but is not limited to, any warranty of the quality, + # performance, merchantability and fitness for a particular purpose of + # the program and the nonexistence of any infringement or violation of + # any right of any third party. + # + # Each user of the program will agree and understand, and be deemed to + # have agreed and understood, that there is no warranty whatsoever for + # the program and, accordingly, the entire risk arising from or + # otherwise connected with the program is assumed by the user. + # + # Therefore, neither ICOT, the copyright holder, or any other + # organization that participated in or was otherwise related to the + # development of the program and their respective officials, directors, + # officers and other employees shall be held liable for any and all + # damages, including, without limitation, general, special, incidental + # and consequential damages, arising out of or otherwise in connection + # with the use or inability to use the program or any product, material + # or result produced or otherwise obtained by using the program, + # regardless of whether they have been advised of, or otherwise had + # knowledge of, the possibility of such damages at any time during the + # project or thereafter. Each user will be deemed to have agreed to the + # foregoing by his or her commencement of use of the program. The term + # "use" as used herein includes, but is not limited to, the use, + # modification, copying and distribution of the program and the + # production of secondary products from the program. + # + # In the case where the program, whether in its original form or + # modified, was distributed or delivered to or received by a user from + # any person, organization or entity other than ICOT, unless it makes or + # grants independently of ICOT any specific warranty to the user in + # writing, such person, organization or entity, will also be exempted + # from and not be held liable to the user for any such damages as noted + # above as far as the program is concerned. + # + # ---------------COPYING.ipadic-----END---------------------------------- + +---------------------------------------------------------------------- + +Lao Word Break Dictionary Data (laodict.txt) + + # Copyright (C) 2016 and later: Unicode, Inc. and others. + # License & terms of use: http://www.unicode.org/copyright.html + # Copyright (c) 2015 International Business Machines Corporation + # and others. All Rights Reserved. + # + # Project: https://github.com/rober42539/lao-dictionary + # Dictionary: https://github.com/rober42539/lao-dictionary/laodict.txt + # License: https://github.com/rober42539/lao-dictionary/LICENSE.txt + # (copied below) + # + # This file is derived from the above dictionary version of Nov 22, 2020 + # ---------------------------------------------------------------------- + # Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell. + # 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. + # -------------------------------------------------------------------------- + +---------------------------------------------------------------------- + +Burmese Word Break Dictionary Data (burmesedict.txt) + + # Copyright (c) 2014 International Business Machines Corporation + # and others. All Rights Reserved. + # + # This list is part of a project hosted at: + # github.com/kanyawtech/myanmar-karen-word-lists + # + # -------------------------------------------------------------------------- + # Copyright (c) 2013, LeRoy Benjamin Sharon + # 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 Myanmar Karen Word Lists, 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. + # -------------------------------------------------------------------------- + +---------------------------------------------------------------------- + +Time Zone Database + + ICU uses the public domain data and code derived from Time Zone +Database for its time zone support. The ownership of the TZ database +is explained in BCP 175: Procedure for Maintaining the Time Zone +Database section 7. + + # 7. Database Ownership + # + # The TZ database itself is not an IETF Contribution or an IETF + # document. Rather it is a pre-existing and regularly updated work + # that is in the public domain, and is intended to remain in the + # public domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do + # not apply to the TZ Database or contributions that individuals make + # to it. Should any claims be made and substantiated against the TZ + # Database, the organization that is providing the IANA + # Considerations defined in this RFC, under the memorandum of + # understanding with the IETF, currently ICANN, may act in accordance + # with all competent court orders. No ownership claims will be made + # by ICANN or the IETF Trust on the database or the code. Any person + # making a contribution to the database or code waives all rights to + # future claims in that contribution or in the TZ Database. + +---------------------------------------------------------------------- + +Google double-conversion + +Copyright 2006-2011, the V8 project 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. + +---------------------------------------------------------------------- + +File: aclocal.m4 (only for ICU4C) +Section: pkg.m4 - Macros to locate and utilise pkg-config. + + +Copyright © 2004 Scott James Remnant . +Copyright © 2012-2015 Dan Nicholson + +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. + +As a special exception to the GNU General Public License, if you +distribute this file as part of a program that contains a +configuration script generated by Autoconf, you may include it under +the same distribution terms that you use for the rest of that +program. + + +(The condition for the exception is fulfilled because +ICU4C includes a configuration script generated by Autoconf, +namely the `configure` script.) + +---------------------------------------------------------------------- + +File: config.guess (only for ICU4C) + + +This file 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 3 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, see . + +As a special exception to the GNU General Public License, if you +distribute this file as part of a program that contains a +configuration script generated by Autoconf, you may include it under +the same distribution terms that you use for the rest of that +program. This Exception is an additional permission under section 7 +of the GNU General Public License, version 3 ("GPLv3"). + + +(The condition for the exception is fulfilled because +ICU4C includes a configuration script generated by Autoconf, +namely the `configure` script.) + +---------------------------------------------------------------------- + +File: install-sh (only for ICU4C) + + +Copyright 1991 by the Massachusetts Institute of Technology + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of M.I.T. not be used in advertising or +publicity pertaining to distribution of the software without specific, +written prior permission. M.I.T. makes no representations about the +suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-ini4j.txt b/tools/third-party-licenses/licenses/java/LICENSE-ini4j.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-ini4j.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-jakarta.annotation-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-jakarta.annotation-api.txt new file mode 100644 index 0000000000..e55f34467e --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jakarta.annotation-api.txt @@ -0,0 +1,277 @@ +Eclipse Public License - v 2.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 content + 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 changes or additions to the Program that + are not Modified Works. + +"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 +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +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. + + 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 or other 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. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other 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 other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +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, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, 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, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, 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. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jakarta.validation-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-jakarta.validation-api.txt new file mode 100644 index 0000000000..e55f34467e --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jakarta.validation-api.txt @@ -0,0 +1,277 @@ +Eclipse Public License - v 2.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 content + 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 changes or additions to the Program that + are not Modified Works. + +"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 +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +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. + + 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 or other 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. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other 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 other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +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, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, 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, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, 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. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jaxb-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-jaxb-api.txt new file mode 100644 index 0000000000..833a843cfe --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jaxb-api.txt @@ -0,0 +1,274 @@ +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. 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 VERSION 2 + +Certain source files distributed by Oracle are subject to the following clarification and special exception to the GPL Version 2, 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 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. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jaxb-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-jaxb-core.txt new file mode 100644 index 0000000000..833a843cfe --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jaxb-core.txt @@ -0,0 +1,274 @@ +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. 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 VERSION 2 + +Certain source files distributed by Oracle are subject to the following clarification and special exception to the GPL Version 2, 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 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. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jaxb-impl.txt b/tools/third-party-licenses/licenses/java/LICENSE-jaxb-impl.txt new file mode 100644 index 0000000000..833a843cfe --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jaxb-impl.txt @@ -0,0 +1,274 @@ +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. 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 VERSION 2 + +Certain source files distributed by Oracle are subject to the following clarification and special exception to the GPL Version 2, 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 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. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-jaxen.txt b/tools/third-party-licenses/licenses/java/LICENSE-jaxen.txt new file mode 100644 index 0000000000..f58a621069 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jaxen.txt @@ -0,0 +1,33 @@ +/* + $Id$ + + Copyright 2003-2006 The Werken Company. 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 Jaxen 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-census-instrumentation-opencensus-proto.txt b/tools/third-party-licenses/licenses/java/LICENSE-jboss-logging.txt similarity index 100% rename from tools/third-party-licenses/licenses/go/LICENSE-github.com-census-instrumentation-opencensus-proto.txt rename to tools/third-party-licenses/licenses/java/LICENSE-jboss-logging.txt diff --git a/tools/third-party-licenses/licenses/java/LICENSE-json-path.txt b/tools/third-party-licenses/licenses/java/LICENSE-json-path.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-json-path.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-json-smart.txt b/tools/third-party-licenses/licenses/java/LICENSE-json-smart.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-json-smart.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-json-utils.txt b/tools/third-party-licenses/licenses/java/LICENSE-json-utils.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-json-utils.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-jul-to-slf4j.txt b/tools/third-party-licenses/licenses/java/LICENSE-jul-to-slf4j.txt new file mode 100644 index 0000000000..3cfcca523f --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-jul-to-slf4j.txt @@ -0,0 +1,25 @@ +Copyright (c) 2023 Tokio 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/java/LICENSE-log4j-slf4j2-impl.txt b/tools/third-party-licenses/licenses/java/LICENSE-log4j-slf4j2-impl.txt new file mode 100644 index 0000000000..98a324cf06 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-log4j-slf4j2-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-metrics-spi.txt b/tools/third-party-licenses/licenses/java/LICENSE-metrics-spi.txt new file mode 100644 index 0000000000..52823540de --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-metrics-spi.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-mongodb-driver-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-mongodb-driver-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-mongodb-driver-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-mongodb-driver.txt b/tools/third-party-licenses/licenses/java/LICENSE-mongodb-driver.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-mongodb-driver.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-mysql-binlog-connector-java.txt b/tools/third-party-licenses/licenses/java/LICENSE-mysql-binlog-connector-java.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-mysql-binlog-connector-java.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-mysql-connector-j.txt b/tools/third-party-licenses/licenses/java/LICENSE-mysql-connector-j.txt new file mode 100644 index 0000000000..1958edc22f --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-mysql-connector-j.txt @@ -0,0 +1,1386 @@ +Licensing Information User Manual + +MySQL Connector/J 8.2.0 Community + __________________________________________________________________ + +Introduction + + This License Information User Manual contains Oracle's product license + and other licensing information, including licensing information for + third-party software which may be included in this distribution of + MySQL Connector/J 8.2.0 Community. + + Last updated: September 2023 + +Licensing Information + + This release of MySQL Connector/J 8.2.0 Community is brought to you by + the MySQL team at Oracle. This software is released under version 2 of + the GNU General Public License (GPLv2), as set forth below, with the + following additional permissions: + + This distribution of MySQL Connector/J 8.2.0 Community is distributed + with certain software that is licensed under separate terms, as + designated in a particular file or component or in the license + documentation. Without limiting your rights under the GPLv2, the + authors of MySQL hereby grant you an additional permission to link the + program and your derivative works with the separately licensed software + that they have included with the program. + + Without limiting the foregoing grant of rights under the GPLv2 and + additional permission as to separately licensed software, this + Connector is also subject to the Universal FOSS Exception, version 1.0, + a copy of which is reproduced below and can also be found along with + its FAQ at http://oss.oracle.com/licenses/universal-foss-exception. + + Copyright (c) 2017, 2023, Oracle and/or its affiliates. + +Election of GPLv2 + + For the avoidance of doubt, except that if any license choice other + than GPL or LGPL is available it will apply instead, Oracle elects to + use only the General Public License version 2 (GPLv2) at this time for + any software where a choice of GPL license versions is made available + with the language indicating that GPLv2 or any later version may be + used, or where a choice of which version of the GPL is applied is + otherwise unspecified. + +GNU General Public License Version 2.0, June 1991 + +The following applies to all products licensed under the GNU General +Public License, Version 2.0: You may not use the identified files +except in compliance with the GNU General Public License, Version +2.0 (the "License.") You may obtain a copy of the License at +http://www.gnu.org/licenses/gpl-2.0.txt. A copy of the license is +also reproduced below. Unless required by applicable law or agreed +to in writing, software distributed under the License is distributed +on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +either express or implied. See the License for the specific language +governing permissions and limitations under the License. + + + ====================================================================== + ====================================================================== + + +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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. + + GNU GENERAL PUBLIC LICENSE + 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. + + + 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-1301 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. + + , 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 Lesser General Public License instead of this License. + + ====================================================================== + ====================================================================== + +The Universal FOSS Exception, Version 1.0 + + In addition to the rights set forth in the other license(s) included in + the distribution for this software, data, and/or documentation + (collectively the "Software", and such licenses collectively with this + additional permission the "Software License"), the copyright holders + wish to facilitate interoperability with other software, data, and/or + documentation distributed with complete corresponding source under a + license that is OSI-approved and/or categorized by the FSF as free + (collectively "Other FOSS"). We therefore hereby grant the following + additional permission with respect to the use and distribution of the + Software with Other FOSS, and the constants, function signatures, data + structures and other invocation methods used to run or interact with + each of them (as to each, such software's "Interfaces"): + + i. The Software's Interfaces may, to the extent permitted by the + license of the Other FOSS, be copied into, used and distributed in + the Other FOSS in order to enable interoperability, without + requiring a change to the license of the Other FOSS other than as + to any Interfaces of the Software embedded therein. The Software's + Interfaces remain at all times under the Software License, + including without limitation as used in the Other FOSS (which upon + any such use also then contains a portion of the Software under the + Software License). + + ii. The Other FOSS's Interfaces may, to the extent permitted by the + license of the Other FOSS, be copied into, used and distributed in + the Software in order to enable interoperability, without requiring + that such Interfaces be licensed under the terms of the Software + License or otherwise altering their original terms, if this does + not require any portion of the Software other than such Interfaces + to be licensed under the terms other than the Software License. + + iii. If only Interfaces and no other code is copied between the + Software and the Other FOSS in either direction, the use and/or + distribution of the Software with the Other FOSS shall not be + deemed to require that the Other FOSS be licensed under the license + of the Software, other than as to any Interfaces of the Software + copied into the Other FOSS. This includes, by way of example and + without limitation, statically or dynamically linking the Software + together with Other FOSS after enabling interoperability using the + Interfaces of one or both, and distributing the resulting + combination under different licenses for the respective portions + thereof. + + For avoidance of doubt, a license which is OSI-approved or + categorized by the FSF as free, includes, for the purpose of this + permission, such licenses with additional permissions, and any + license that has previously been so approved or categorized as + free, even if now deprecated or otherwise no longer recognized as + approved or free. Nothing in this additional permission grants any + right to distribute any portion of the Software on terms other than + those of the Software License or grants any additional permission + of any kind for use or distribution of the Software in conjunction + with software other than Other FOSS. + + ====================================================================== + ====================================================================== + +Licenses for Third-Party Components + + The following sections contain licensing information for libraries that + may be included with this product. We are thankful to all individuals + that have created these. Standard licenses referenced herein are + detailed in the Standard Licenses section. + +c3p0 JDBC Library + +The MySQL Connector/J implements interfaces that are included in +c3p0, although no part of c3p0 is included or distributed with +MySQL. + +Copyright (C) 2019 Machinery For Change, Inc. + + * This library is free software; you can redistribute it and/or modify + * it under the terms of EITHER: + * + * 1) The GNU Lesser General Public License (LGPL), version 2.1, as + * published by the Free Software Foundation + * + * OR + * + * 2) The Eclipse Public License (EPL), version 1.0 + * You may choose which license to accept if you wish to redistribute + * or modify this work. You may offer derivatives of this work + * under the license you have chosen, or you may provide the same + * choice of license which you have been offered here. + * + * This software 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. + * + * You should have received copies of both LGPL v2.1 and EPL v1.0 + * along with this software; see the files LICENSE-EPL and LICENSE-LGPL. + * If not, the text of these licenses are currently available at + * + * LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + * EPL v1.0: http://www.eclipse.org/org/documents/epl-v10.php + +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 additionsto +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. + +The LGPL v2.1 can be found in +GNU Lesser General Public License v2.1, February 1999. +See the 'Standard Licenses' section for license text. + + ====================================================================== + ====================================================================== + +Google Protocol Buffers + +Copyright 2008 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Code generated by the Protocol Buffer compiler is owned by the owner +of the input file used when generating it. This code is not +standalone and requires a support library to be linked with it. This +support library is itself covered by the above license. + + ====================================================================== + ====================================================================== + +Unicode Data Files + +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1991-2014 Unicode, Inc. All rights reserved. Distributed under +the Terms of Use in http://www.unicode.org/copyright.html. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the Unicode data files and any associated documentation (the "Data Files") +or Unicode software and any associated documentation (the "Software") to deal +in the Data Files or Software without restriction, including without +limitation the rights to use, copy, modify, merge, publish, distribute, +and/or sell copies of the Data Files or Software, and to permit persons to +whom the Data Files or Software are furnished to do so, provided that (a) the +above copyright notice(s) and this permission notice appear with all copies +of the Data Files or Software, (b) both the above copyright notice(s) and +this permission notice appear in associated documentation, and (c) there is +clear notice in each modified Data File or in the Software as well as in the +documentation associated with the Data File(s) or Software that the data or +software has been modified. + +THE DATA FILES AND SOFTWARE ARE 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 OF THIRD +PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 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 THE DATA FILES OR +SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +these Data Files or Software without prior written authorization of the +copyright holder. + + ====================================================================== + ====================================================================== + +Standard Licenses + +GNU Lesser General Public License v2.1, February 1999 + +The following applies to all products licensed under the +GNU Lesser General Public License, Version 2.1: You may +not use the identified files except in compliance with +the GNU Lesser General Public License, Version 2.1 (the +"License"). You may obtain a copy of the License at +http://www.gnu.org/licenses/lgpl-2.1.html. A copy of the +license is also reproduced below. Unless required by +applicable law or agreed to in writing, software distributed +under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +or implied. See the License for the specific language governing +permissions and limitations under the License. + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +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 and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs +must be allowed to use the library. A more frequent case is that +a free library does the same job as widely used non-free libraries. +In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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 with +this License. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +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. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + ====================================================================== + ====================================================================== + +Written Offer for Source Code + + For any software that you receive from Oracle in binary form which is + licensed under an open source license that gives you the right to + receive the source code for that binary, you can obtain a copy of the + applicable source code by visiting + http://www.oracle.com/goto/opensourcecode. If the source code for the + binary was not provided to you with the binary, you can also receive a + copy of the source code on physical media by submitting a written + request to the address listed below or by sending an email to Oracle + using the following link: + http://www.oracle.com/goto/opensourcecode/request. + + Oracle America, Inc. + Attn: Senior Vice President + Development and Engineering Legal + 500 Oracle Parkway, 10th Floor + Redwood Shores, CA 94065 + + Your request should include: + + * The name of the binary for which you are requesting the source code + + * The name and version number of the Oracle product containing the + binary + + * The date you received the Oracle product + + * Your name + + * Your company name (if applicable) + + * Your return mailing address and email, and + + * A telephone number in the event we need to reach you. + + + We may charge you a fee to cover the cost of physical media and + processing. + + Your request must be sent + + a. within three (3) years of the date you received the Oracle product + that included the binary that is the subject of your request, or + + b. in the case of code licensed under the GPL v3 for as long as Oracle + offers spare parts or customer support for that product model. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-netty-nio-client.txt b/tools/third-party-licenses/licenses/java/LICENSE-netty-nio-client.txt new file mode 100644 index 0000000000..e25e752cf1 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-netty-nio-client.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-oapi-sdk.txt b/tools/third-party-licenses/licenses/java/LICENSE-oapi-sdk.txt new file mode 100644 index 0000000000..1a7891acd6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-oapi-sdk.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-openapiutil.txt b/tools/third-party-licenses/licenses/java/LICENSE-openapiutil.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-openapiutil.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-org.abego.treelayout.core.txt b/tools/third-party-licenses/licenses/java/LICENSE-org.abego.treelayout.core.txt new file mode 100644 index 0000000000..6ab50a1fc6 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-org.abego.treelayout.core.txt @@ -0,0 +1,28 @@ +abego Public Licence Version 1.0 + +Copyright (c) 2006, abego Software GmbH (http://www.abego-software.de) + +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 abego Software 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-org.jacoco.agent.txt b/tools/third-party-licenses/licenses/java/LICENSE-org.jacoco.agent.txt new file mode 100644 index 0000000000..e55f34467e --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-org.jacoco.agent.txt @@ -0,0 +1,277 @@ +Eclipse Public License - v 2.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 content + 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 changes or additions to the Program that + are not Modified Works. + +"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 +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +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. + + 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 or other 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. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other 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 other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +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, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, 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, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, 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. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + 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. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-profiles.txt b/tools/third-party-licenses/licenses/java/LICENSE-profiles.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-profiles.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-protocol-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-protocol-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-protocol-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-pull-parser.txt b/tools/third-party-licenses/licenses/java/LICENSE-pull-parser.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-pull-parser.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-runtime.txt b/tools/third-party-licenses/licenses/java/LICENSE-runtime.txt new file mode 100644 index 0000000000..83290392f8 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-runtime.txt @@ -0,0 +1,28 @@ +Copyright (c) 2012-2022 The ANTLR Project. 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. + +3. Neither name of copyright holders 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 REGENTS 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-s3.txt b/tools/third-party-licenses/licenses/java/LICENSE-s3.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-s3.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-sdk-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-sdk-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-sdk-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-slack-api-client.txt b/tools/third-party-licenses/licenses/java/LICENSE-slack-api-client.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-slack-api-client.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-slack-api-model.txt b/tools/third-party-licenses/licenses/java/LICENSE-slack-api-model.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-slack-api-model.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-slack-app-backend.txt b/tools/third-party-licenses/licenses/java/LICENSE-slack-app-backend.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-slack-app-backend.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-spring-aop.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-aop.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-aop.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-spring-beans.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-beans.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-beans.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-spring-boot-autoconfigure.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot-autoconfigure.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot-autoconfigure.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-spring-boot-starter-logging.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot-starter-logging.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot-starter-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. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-spring-boot-starter-validation.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot-starter-validation.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot-starter-validation.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-spring-boot-starter.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot-starter.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot-starter.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-spring-boot.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-boot.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-spring-context.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-context.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-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-spring-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-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-spring-expression.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-expression.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-expression.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-spring-jcl.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-jcl.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-jcl.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-spring-messaging.txt b/tools/third-party-licenses/licenses/java/LICENSE-spring-messaging.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-spring-messaging.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-stax-api.txt b/tools/third-party-licenses/licenses/java/LICENSE-stax-api.txt new file mode 100644 index 0000000000..e72bfddabc --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-stax-api.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU 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 Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/tools/third-party-licenses/licenses/java/LICENSE-tea-openapi.txt b/tools/third-party-licenses/licenses/java/LICENSE-tea-openapi.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-tea-openapi.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-tea-util.txt b/tools/third-party-licenses/licenses/java/LICENSE-tea-util.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-tea-util.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-tea-xml.txt b/tools/third-party-licenses/licenses/java/LICENSE-tea-xml.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-tea-xml.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-tea.txt b/tools/third-party-licenses/licenses/java/LICENSE-tea.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-tea.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-third-party-jackson-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-third-party-jackson-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-third-party-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. diff --git a/tools/third-party-licenses/licenses/java/LICENSE-tomcat-embed-el.txt b/tools/third-party-licenses/licenses/java/LICENSE-tomcat-embed-el.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-tomcat-embed-el.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-utils.txt b/tools/third-party-licenses/licenses/java/LICENSE-utils.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-utils.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-vertx-auth-common.txt b/tools/third-party-licenses/licenses/java/LICENSE-vertx-auth-common.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-vertx-auth-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-vertx-bridge-common.txt b/tools/third-party-licenses/licenses/java/LICENSE-vertx-bridge-common.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-vertx-bridge-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-vertx-core.txt b/tools/third-party-licenses/licenses/java/LICENSE-vertx-core.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-vertx-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-vertx-web-client.txt b/tools/third-party-licenses/licenses/java/LICENSE-vertx-web-client.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-vertx-web-client.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-vertx-web-common.txt b/tools/third-party-licenses/licenses/java/LICENSE-vertx-web-common.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-vertx-web-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-vertx-web.txt b/tools/third-party-licenses/licenses/java/LICENSE-vertx-web.txt new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-vertx-web.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-xpp3.txt b/tools/third-party-licenses/licenses/java/LICENSE-xpp3.txt new file mode 100644 index 0000000000..203f4e462e --- /dev/null +++ b/tools/third-party-licenses/licenses/java/LICENSE-xpp3.txt @@ -0,0 +1,45 @@ +The Apache Software License, Version 1.1 + + Copyright (c) 2000 The Apache Software Foundation. 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. + + 3. The end-user documentation included with the redistribution, + if any, must include the following acknowledgment: + "This product includes software developed by the + Apache Software Foundation (http://www.apache.org/)." + Alternately, this acknowledgment may appear in the software itself, + if and wherever such third-party acknowledgments normally appear. + + 4. The names "Apache" and "Apache Software Foundation" must + not be used to endorse or promote products derived from this + software without prior written permission. For written + permission, please contact apache@apache.org. + + 5. Products derived from this software may not be called "Apache", + nor may "Apache" appear in their name, without prior written + permission of the Apache Software Foundation. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR + ITS 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-envoyproxy-protoc-gen-validate.txt b/tools/third-party-licenses/licenses/java/LICENSE-zookeeper-jute.txt similarity index 100% rename from tools/third-party-licenses/licenses/go/LICENSE-github.com-envoyproxy-protoc-gen-validate.txt rename to tools/third-party-licenses/licenses/java/LICENSE-zookeeper-jute.txt